ホーム > mysql > MySQLではまったこと

MySQLではまったこと

MySQL4.0はサーバがキャラクタセットをもっており、クライアントはサーバのキャラクタセットで動作していた。
4.1、5.0はクライアントとサーバで別々にキャラクタセットを持っており、変換が行われる。
クライアントとサーバで相互変換できないキャラクタセットの場合、データが壊れる(文字化け)が起こる。

ここまでは別に問題なかった。

PHPはデフォルトでキャラクタセットlatin1を利用するようになっている。
なので配布されているバイナリのほとんどはキャラクタセットlatin1。

ここまでも問題なし。

my.cnf(Windowsバイナリだとmy.ini)の設定項目でキャラクタセットに関係あるもの。

mysql> SHOW VARIABLES LIKE 'char%';
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |

[mysqld] — mysqlサーバの設定。
「character-set-server」「default-character-set」とキャラクタセットを2つ設定しているのをみるが、両方書いてもどちらか一方でも動作はかわらず。
「default-character-set」でサーバのキャラクタセットがすべて初期化されるけど、その対象が「character-set-server」という話ぽい。
5.0.13rc以降なら「skip-character-set-client-handshake」を設定することにより、4.0以前と同様の文字変換を行わない設定にできる。
[mysql] — mysqlクライアントの設定。
コマンドラインmysqlの設定。
「default-character-set」で設定したキャラクタセットが「character_set_client」「character_set_connection」「character_set_results」に反映される。
PHPで利用する場合はここに何設定しようが反映されない。
[mysqldump] — mysqldumpの設定。
何も設定しない場合、デフォルトでutf8と設定されている。
無変換で出力したい場合はキャラクタセットbinaryを指定する。

ここで、罠に引っかかる。
my.cnfに「init-connect=SET NAMES 文字コード」を設定すればサーバに接続したクライアントのキャラクタセットを初期化できる…という情報がたくさんあったんだけど、PHPからMySQLへ接続し「SHOW VARIABLES LIKE ‘char%’;」をクエリして結果みてみたら、「SET NAMES 文字コード」反映されてねぇぇぇぇ!
盲目に信じてた自分がバカだったんですが。
ちなみPHP5.1.2とPHP5.0.4。
[追記] init-connectはSUPER権限のユーザだと反映されないらしい?
「SET NAMES キャラクタセット」をクエリすると「character_set_client」「character_set_connection」「character_set_results」の値を変更できる。

あと、もうひとつはまったこと。
「SHOW VARIABLES LIKE ‘char%’;」クエリした結果の「character_set_server」。
DBを作成する場合のデフォルトのキャラクタセットの意味しかないとずっと思ってたんだけど、設定変えたら全体の動作変わった。
CREATE DATABESEでDB作る時にキャラクタセット指定しないと「character_set_database」が「character_set_server」の値になるんだけど、これが参照になってるので既存のDBのキャラクタセットすべて書き変わる。
稼働中のシステムの変更する場合は、まったく同じ環境つくってから設定変えていくって形とらないと。
同じ環境を作成するの厳しかったので、別環境を1から構築して、そこでいろいろ設定して試してたんですが、元のmy.cnfの設定をチェックしてなかったよフフフ。

PHPとMySQL4.1(〜5.0.12)のセットで利用する場、phpスクリプトに手を加えたくない場合はlibmysqlをコンパイルし直すかなさげ。
my.cnfはPHP5を利用するならphp_mysqliでなら読めるように設定できるらしい。
すべてlatin1で統一してある場合は、一見問題なく動作してるようにみえるが、マルチバイト文字がシングルバイト文字(実際は文字とは言えない何か)×Nと処理されるため、varchar(60)が文字数ではなくバイト数と同じような処理をしてしまう。
phpMyAdmin使えないし。

カテゴリー: mysql タグ:
  1. コメントはまだありません。
  1. トラックバックはまだありません。