Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
文字化け
文字化けは、日本語を扱う限り、最も注意しないといけない。 データベースでは文字が化けてしまっては最悪である。 些細な文字化けだし、見れば意図していることは分るではないかという 考え方は危険である。 データは人間が見ている間はそれでも良いかもしれないが、 そのデータを利用して自動的に様々な処理を行なうようなことを 必ず行なうようになるので、些細なことが大きなトラブルに繋がってしまう。
MySQLも、いろいろ調べていたら、どうも文字化けというか、 勝手に文字を変更してくれることがある。 今回から、そのあたりを旅してみようと思う。
サーバ側(sjis) - - - - クライアント側(sjis)
端末の文字コードを Shift-JIS にして、以下を行なってみた。
mysql> SET NAMES sjis; Query OK, 0 rows affected (0.00 sec) mysql> SELECT '\\'; +----+ | \ | +----+ | \ | +----+ 1 row in set (0.00 sec)
SET NAMES で使用するキャラクタセットを端末に合わせて シフトJISにした。
そして \(端末がSJISなので、半角の¥マーク)だけの文字列を試してみると、 不思議なことになってしまった。 上側は全角の逆スラッシュ、下側は¥マークになったのである。 (\は使用しているブラウザの設定によって見え方が変るかも)
それにしても、なぜ上だけが全角の\になってしまうのか。
'\\' と \ が2つ続いているのは、\ はエスケープになるので、 もう1つ書かなければならない。エスケープの意味については説明するのが 面倒なので、知らない人はどこかで調べて下さい。
さて、文字列がどうなっているか分らないときにやるべきことは、 HEX()を使って16進数表示するのが常套手段である。
mysql> SELECT HEX('\\');
+-------------+
| HEX('\\') |
+-------------+
| 5C |
+-------------+
1 row in set (0.00 sec)
ますます怪しいことになってきた。 SELECT HEX('\\') というSQL文をMySQLサーバに送ったのだが、 上の段は、HEX('\\') というとんでもない表示になってしまった。
どうも、\ は \ になってしまうようだ。
現在のキャラクタセット関連のシステム変数を見てみよう。
mysql> SHOW VARIABLES LIKE 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | sjis | | character_set_connection | sjis | | character_set_database | latin1 | | character_set_results | sjis | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+--------+ 6 rows in set (0.00 sec)
とくに異常はないようだが、摩訶不思議な変換をしてくれる。
サーバ側(ujis) - - - - クライアント側(sjis)
mysql> SET character_set_connection=ujis; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | sjis | | character_set_connection | ujis | | character_set_database | latin1 | | character_set_results | sjis | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+--------+ 6 rows in set (0.00 sec)
これで、サーバ側が ujis で、クライアント側が sjisになった。 クライアント・サーバ間でキャラクタセットが異なると、その間を 文字が移動するとき、ありがたいことに、ちゃんと変換してくれるのである。
さて、もう一度変換してみよう。
mysql> SELECT '\\'; +----+ | \ | +----+ | \ | +----+ 1 row in set (0.00 sec)
こんどは、上も下も全角の \ になってしまった。
どうも今日は mysql の御機嫌が斜めなのか、訳の分らない変換を施してくれる。 また日を改めて調べることにしよう。
フィードバック: