Google
SSブログ

mysql の文字化け対策 [メモ]


状況
  Windows環境で、インストールした mysql に作成したDB・テーブルの VARCHAR 列に日本語を INSERT し、SELECT した際に文字化けする。

ちょっと前に、Javaの講習を受けていて、Eclipse + mysql を使用していた。
(講習ではスクール用にカスタマイズされたXAMPPのインストーラを使用して環境構築)
その時は mysql 絡みでの文字化けは特に発生していなかった。

スクールのカスタマイズしたXAMPPのインストーラから見て取れる情報
  XAMPP(version 1.7.1)
  mysql(Ver 14.14 Distrib 5.1.33, for Win32 (ia32))


自分の環境で同様に開発作業をしていたが、mysql に作成したDB・テーブルの VARCHAR 列に日本語を INSERT し、SELECT した際に文字化けしてしまう。

色々と検索してみたところ、多様な情報が存在していた。

【1】mysql の文字コードの設定を調べる方法が2種類あって、下記の2つ
  ①  mysql> show variables like 'character_set%';
  ②  mysql> status

それぞれの結果は以下
①:
+--------------------------+----------------------------------------------+
| Variable_name            | Value                                        |
+--------------------------+----------------------------------------------+
| character_set_client     | latin1                                       |
| character_set_connection | latin1                                       |
| character_set_database   | latin1                                       |
| character_set_filesystem | binary                                       |
| character_set_results    | latin1                                       |
| character_set_server     | latin1                                       |
| character_set_system     | utf8                                         |
| character_sets_dir       | C:\Program Files\xampp\mysql\share\charsets\ |
+--------------------------+----------------------------------------------+
8 rows in set (0.00 sec)

②:
--------------
mysql  Ver 14.14 Distrib 5.1.41, for Win32 (ia32)

Connection id:          1
SSL:                    Not in use
Using delimiter:        ;
Server version:         5.1.41 Source distribution
Protocol version:       10
Connection:             localhost via TCP/IP
Client characterset:    latin1
Server characterset:    latin1
TCP port:               3306
Uptime:                 47 min 23 sec

Threads: 1  Questions: 4  Slow queries: 0  Opens: 19  Flush tables: 1  Open tables: 0  Queries per second avg: 0.1
--------------


スクールのカスタマイズインストーラから入れた mysql では、上記の latin1 の部分が全て sjis であった。

で、mysql の文字コードの設定について検索してみたところ、


【2】設定ファイル my.ini とか my.cnf が存在し、それを編集して mysql を再起動すればよい。

とにかく設定ファイルに関しては様々なページがヒットしたが、mysql のバージョンもOS環境も様々のため、情報に一貫性が無かった。
それぞれ書かれた内容に沿って試してみたところ、私の環境と一致するものと一致しないものがあった。

試してみた結果から現時点で私が推測しているのは、
・mysql の設定ファイルは、基本的にLinux環境では /etc/my.cnf であり、Windows環境では インストールフォルダ\xampp\mysql\bin\my.ini である。
・単なる設定ファイルなので、環境によっては Windows環境でも my.cnf の設定を反映させることも可能である。
・Windowsマシン上の mysql 5.1.41 では、サーバ、クライアントが物理的に1つのマシンに同居している場合、サーバーの起動とクライアントの起動で設定ファイルからの反映に関してのデフォルトのルールが異なり、サーバは my.ini を反映するが、クライアントは特に設定ファイルを反映しない。


いくつも疑問符は残るが、上記の推測を元に下記の流れで文字化け対策とした。

【対策1】インストールフォルダ\xampp\mysql\bin\my.ini の中の [mysqld] の部分に下記を追加
    default-character-set=sjis

  ※いろんなページで、さらにこの下に
    skip-character-set-client-handshake
    を足したと書かれていたが、ここの忠告に従って書き足さないこととした。

skip-character-set-client-handshake、SET NAMES で文字化けなどの問題を解決してしまうと、SQLインジェクションの脆弱性を生じます。
これらのオプションやコマンドは、文字コードの設定を*無理やり*変えてしまうので、問題の表層だけ解決しまう可能性があります。
文字化け(??になったり、無用な¥が挿入されたり)、SQLインジェクション、がなぜ発生するかというと「サーバ/データベース/クライアント」の文字コードの設定が一致していないからです。
シンプルに解決するには、これらを完全に一致させればよいわけです。



対策1により、サーバーのデフォルトの文字コードが sjis になったとイメージしている。

この時点で、①の結果が下記に変わった
①:
+--------------------------+----------------------------------------------+
| Variable_name            | Value                                        |
+--------------------------+----------------------------------------------+
| character_set_client     | latin1                                       |
| character_set_connection | latin1                                       |
| character_set_database   | sjis                                         |
| character_set_filesystem | binary                                       |
| character_set_results    | latin1                                       |
| character_set_server     | sjis                                         |
| character_set_system     | utf8                                         |
| character_sets_dir       | C:\Program Files\xampp\mysql\share\charsets\ |
+--------------------------+----------------------------------------------+
8 rows in set (0.01 sec)


②の方はまだ変わりない。



【対策2】クライアントは毎回起動オプションで sjis を指定する。
コマンドプロンプトから「mysql -u root」で実行していたが、下記コマンドで起動するようにする。
    mysql --default-character-set=sjis -u root

この時点で、①・②の結果は以下
①:
+--------------------------+----------------------------------------------------+
| Variable_name            | Value                                              |
+--------------------------+----------------------------------------------------+
| character_set_client     | sjis                                               |
| character_set_connection | sjis                                               |
| character_set_database   | sjis                                               |
| character_set_filesystem | binary                                             |
| character_set_results    | sjis                                               |
| character_set_server     | sjis                                               |
| character_set_system     | utf8                                               |
| character_sets_dir       | C:\Program Files\xampp\mysql\share\charsets\ |
+--------------------------+----------------------------------------------------+
8 rows in set (0.01 sec)

②:
--------------
mysql  Ver 14.14 Distrib 5.1.41, for Win32 (ia32)

Connection id:          1
SSL:                    Not in use
Using delimiter:        ;
Server version:         5.1.41 Source distribution
Protocol version:       10
Connection:             localhost via TCP/IP
Client characterset:    sjis
Server characterset:    sjis
TCP port:               3306
Uptime:                 34 sec

Threads: 1  Questions: 4  Slow queries: 0  Opens: 19  Flush tables: 1  Open tables: 12  Queries per
second avg: 0.117
--------------



【対策3】データベース作成時は毎回 character set を指定する。
    create database <dbname> default character set sjis;

これもここを参考にさせて貰った。



しばらくこのやり方で続けてみます。

誤った認識等に気づいた人は是非是非突っ込みをお願いします。
タグ:メモ MySQL 技術
nice!(0)  コメント(2)  トラックバック(0) 

nice! 0

コメント 2

朴杉

大変参考になりました。
自分もここでつまずいていました。
暫くは同じ方法で実行していきます。
もしくは前のバージョンを使用する事になりそうです。
by 朴杉 (2010-04-14 17:53) 

sakashushu

自分もいまいち理屈が分かっていませんが、お役に立ったようで何よりです。
バージョンによる違いもかなりありそうですよね。

by sakashushu (2010-04-14 18:03) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。