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を起動し、何も設定しなかった場合の状態について 調べてみよう。
標準のままのlatin1の場合に漢字は使えるか
mysql> SHOW VARIABLES LIKE 'character\_set\_%'; +--------------------------+--------+ | Variable_name | Value | +--------------------------+--------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | +--------------------------+--------+ 6 rows in set (0.00 sec)
キャラクタ端末は漢字について調べるので、ここでは EUC-JP にしておく。
ここで、漢字文字列の SELECT をやってみよう。
mysql> SELECT '漢字'; +------+ | 漢字 | +------+ | 漢字 | +------+ 1 row in set (0.00 sec)
ujis(EUC-JP)の指定などどこにも無いのに、何だが動いているように見える。
ここで、 SELECT HEX('漢字'); を実行するとどうなるが考えてみよう。 このSQL文は、クライアントからサーバー側に送られて、サーバ側で 関数HEX()が 実行されるはずである。
mysql> SELECT HEX('漢字');
+-------------+
| HEX('漢字') |
+-------------+
| B4C1BBFA |
+-------------+
ちゃんと、UJISとして解釈されているように見える。 たったこれだけで使えると判断するのは無茶苦茶と思うが、 ここまでの段階では、何だか知らぬが、つじつまが勝手に合ってしまったようだ。 でも、これで大丈夫とは思わない方が良いだろう。
クライアントとサーバーのキャラクタセットが異なる場合
ここで、クライアントサーバ間の接続において、サーバ側をujis, クライアント側をsjisにしてみよう。
mysql> SET NAMES sjis; Query OK, 0 rows affected (0.00 sec) 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)
現在、キャラクタ端末は EUC-JP であり、MySQLの character_set_client とは異なっている。
mysql> SELECT '漢字';
+-----+
| 漢? |
+-----+
| 漢? |
+-----+
1 row in set (0.00 sec)
mysql> SELECT HEX('漢字');
+--------------+
| HEX('漢??') |
+--------------+
| 8EB48EC18EBB |
+--------------+
1 row in set (0.00 sec)
この場合、以上のように文字化けが発生し、HEXの出力結果から6バイトの 文字列をMySQLサーバが受け取ったことが判明する。 HEX()の処理がされる前に、 なんらかの予期せぬ文字コードの自動変換がされているのでこうなった。
ここで、キャラクター端末をSHIFT-JISに設定してみよう。
mysql> SELECT '漢字';
+------+
| 漢字 |
+------+
| 漢字 |
+------+
1 row in set (0.00 sec)
mysql> SELECT HEX('漢字');
+-------------+
| HEX('漢字') |
+-------------+
| B4C1BBFA |
+-------------+
1 row in set (0.00 sec)
この16進表記は、ujis(EUC-JP)であることを示している。 つまり、HEX()の引数として与えられた文字列は、ujisであった訳だ。 クライアント側は sjis に設定してあり、 character_set_connection が ujis なので、クライアントから MySQLサーバにSQL文を送りつけるときに、文字列の部分は ujis に変換されたことになる。
要するに、次の図のようにコード変換が行なわれたのかな。
+---------------------------------------------------------------+
| gnome-terminal Character Encoding = SHIFT-JIS |
+---------------------------------------------------------------+
| ↑
|無変換 |無変換
↓ |
+---------------------------------------------------------------+
| mysqlクライアント |
| character_set_client = sjis character_set_results = sjis |
+---------------------------------------------------------------+
| ↑
|自動コード変換 |自動コード変換
↓ |
+---------------------------------------------------------------+
| MySQLサーバ character_set_connection = ujis |
+---------------------------------------------------------------+
character_set_何とかについて説明しなかったが、適当に想像して欲しい。 まあ、そのうち、これら6つの変数の意味についてはきちんと説明しようと思う。 このペースだと、だいぶ先になるかも知れないが。
フィードバック:
There is no comment.