MySQLプロファイルにdefault-character-setの設定を忘れたことによる文字化け問題

7476 ワード

文字セットの参考文献:
http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_character_setconnection
http://dev.mysql.com/doc/refman/5.6/en/faqs-cjk.html
今日、同僚がjdbcを使ってデータベースに接続して、文の結果集がないことを実行しますが、sqlyouを通じて同じ文を実行します。
実行するステートメントwhereの条件には中国語が含まれています。これは文字セットによるものです。
この開発テストの例は移転して間もないので、移行前の環境デフォルトの文字セットはutf 8です。
現在のデータベースの文字セットを表示します。
mysql> show variables like '%charac%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | utf8                             |
| character_set_connection | utf8                             |
| character_set_database   | latin1                           |
| character_set_filesystem | binary                           |
| character_set_results    | utf8                             |
| character_set_server     | latin1                           |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.00 sec)
  • character_setclient    
  • character_setコンサート
  • character_setレスリング
  • 以上の三つのMsql clientを制御する文字セット
  • character_setdatabase 
  •           データベースの標準文字セットを設定します。
  • character_setserver    
  •           以上のすべてのデフォルトの文字セットを設定します。
    server端の文字セットとclient端のグローバルキャラクタセット設定変数は、いずれも標準値latin 1であることが分かりました。
    設定ファイルにパラメータ項目が追加されていないことが分かりました。  character-set-server=utf 8
    文字化けの原因:
    データ格納時の符号化復号処理
    jdbc=>character_setclient=>table character
    各環節の文字セットコードは全部utf 8で、トランスコードプロセスがありません。
    character_setclientがlatin 1になったら、データを読み込む復号処理は
    jdbc<=character_setclient<=table character
    表にはutf 8符号化フォーマットが格納されています。判断とcharacter_setclientが一致しない場合は、latin 1のバイナリストリームにトランスコードし、リモート端末のクライアントに送信します。
    クライアントjdbcは、設定された文字セットによって結果を示し、utf 8を用いてlatin 1を示しているので、文字化けが発生している。
    解決策
    # character_set_filesystem 、character_set_system 、character_sets_dir        utf8
    すべてのアプリケーションは、セッションレベルの文字セットを変更するには、データベースを再接続する必要があります。
    文字セットがlatin 1に設定されている間に挿入されるデータ符号化格納プロセスについて:
  • は、terminal(ここではjdbcクライアント)に入力方式を用いて入力する
  • である。
  • terminalは、utf 8バイナリストリーム
  • に変換される。
  • バイナリストリームは、MySQLクライアントを介してMySQL Server
  • に転送される。
  • Serverは、character-set-clientによって
  • を復号する。
  • は、character-set-clientとターゲットテーブルのcharsetが一致するかどうかを判断し、character-set-clientはlatin 1であり、ターゲットテーブルの文字セットはutf 8
  • である。
  • が一致しない場合は、client-charsetからtable-charsetまでの一回の文字コード変換を行い、latin 1からutf 8
  • にトランスコードされる。
  • 変換された文字コードのバイナリストリームをファイルに保存します。
  • テストの場合、中間環節のcharacter-set-clientをutf 8に変更して、文字化けが発生するかどうか
    mysql> show  variables like '%char%';      
    +--------------------------+----------------------------------+
    | Variable_name            | Value                            |
    +--------------------------+----------------------------------+
    | character_set_client     | latin1                           |
    | character_set_connection | latin1                           |
    | character_set_database   | utf8                             |
    | character_set_filesystem | binary                           |
    | character_set_results    | latin1                           |
    | character_set_server     | utf8                             |
    | character_set_system     | utf8                             |
    | character_sets_dir       | /usr/local/mysql/share/charsets/ |
    +--------------------------+----------------------------------+
    8 rows in set (0.01 sec)
    
    mysql> update t1 set col='   ' where id=4;    
    
    mysql> select * from t1 where id=4;
    +----+-----------+------+
    | id | col       | time |
    +----+-----------+------+
    |  4 |        | NULL |
    +----+-----------+------+
    
    
          
    
    crt terminal =》character_set_client =》character_set_server
    		utf8          latin1                 utf8			
                             
                     
    1、         
    mysql> set names utf8;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select * from t1 where id=4;
    +----+-----------------------+------+
    | id | col                   | time |
    +----+-----------------------+------+
    |  4 | ??o???è??             | NULL |
    +----+-----------------------+------+
    2、  crt terminal      default
    mysql> select * from t1 where id=4;
    +----+-----------+------+
    | id | col       | time |
    +----+-----------+------+
    |  4 |        | NULL |
    +----+-----------+------+
    3、        
    ALTER TABLE t1 CHANGE col col varchar(10) CHARACTER SET latin1;
    
    mysql> select * from t1 where id=4;
    +----+-----------+------+
    | id | col       | time |
    +----+-----------+------+
    |  4 |        | NULL |
    +----+-----------+------+
    
     表の文字セットを変更するとlatin 1になります。データの読み込みは変更に関連しています。
  • ファイルからバイナリデータストリームを読み出します。
  • は、表文字セットlatin 1で符号化して復号する
  • は、データをcharacter-set-clientの符号化laint 1
  • に変換する。
    対応の変更前の一環:
  • ファイルからバイナリデータストリームを読み出します。
  • は、表文字セットutf 8で符号化して復号する
  • は、データをcharacter-set-clientの符号化laint 1
  • に変換する。
    表データの文字セットを変更しても、文字セット全体が経験している復号とトランスコードのプロセスが一致しているため、一度にutf 8からlatin 1へのトランスコードを経験していることが分かります。
    もう一つの文字セットに関する問題:表情記号をサポートするために、システムレベルのutf 8をutf 8 mb 4に設定し、対応するテーブルも文字セットの変更をしました。再起動アプリケーションは有効ではなく、データベースとアプリケーションを再起動してから有効になります。
    参考記事は以下の通りです
    http://blog.sina.com.cn/s/blog_93 b 45 b 0 f 0101 glfx.
    参考記事:
    符号化復号プロセス  : http://cenalulu.github.io/mysql/mysql-mojibake/
     
    転載先:https://www.cnblogs.com/Bccd/p/5941415.html