Open Source WEB

さて、ここでバイナリの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つの変数の意味についてはきちんと説明しようと思う。 このペースだと、だいぶ先になるかも知れないが。


戻る:HEX()で文字列を16進文字列に変換

次へ:16進数表記から文字列を作る


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us