MySQL 4.1 以降に発生する文字化け問題 – まとめ

【この記事の所要時間 : 約 9 分

mysql_mojibake_taisaku.jpg
MySQL 4.1 以降に発生する文字化けについて、世間では既知の問題らしいが、ネット上では意外とまとまった回答が載っていない。(しっかり探せばあるけど)
まず基本として、MySQL 4.1以降では、サーバ側とクライアント側でそれぞれ文字コードが設定できる。そして、サーバ(mysqld)側では以下の4つの単位で文字コードをそれぞれ設定できる。指定されていない場合は、大きい単位の指定が引き継がれる。
1.サーバ全体
2.データベース(スキーマ)
3.テーブル
4.カラム
このうち最も大きい単位であるサーバ全体における文字コードを、ここでは、デフォルトキャラクターセットと呼ぶことにする。まずこのデフォルトキャラクターセットの設定はというと、インストール時がポイントである。
mysqlインストール時における文字コード(デフォルトキャラクターセット)の設定は、以下の方法でできる。
・ソースからインストールする場合
以下のようにconfigure時に設定できる。

# ./configure –with-charset=**** -with-extra-charsets=all

・RPMパッケージからインストールする場合

デフォルトキャラクタセット = latin1 となる。

そして、確認するには以下のSQLにて、「character_set_server」をみればOK。

mysql> SHOW VARIABLES LIKE ‘%character\_set%’;

次に、サーバ全体より小さい単位のデータベース、テーブル、カラムの文字コード設定は、それぞれの作成時、つまり CREATE DATABASE または、CREATE TABLE において、CHARACTER SET オプションにて設定することができる。ただし、極力、サーバ(サーバ全体、データベース、テーブル、カラム)側の文字コードは、統一しておいた方がいいので、サーバ全体だけ文字コードを設定しておき、CREATE TABLE文やCREATE DATABASE文では文字コードの指定をせず、サーバ全体の文字コード(デフォルトキャラクターセット)に統一しておいた方がいい。
上記をふまえた上で、Q&A方式でMySQL 4.1 以降に発生する文字化け対策について書いていきたいと思う。
1.なぜMySQL 4.1 以降では文字化けが発生するのか?

MySQL4.1 以降、サーバ(mysqld)とクライアント(mysql,phpなど)で別々の文字コードを設定することができ、サーバとクライアントにて自動的に文字コード変換を行うようになった。そのためサーバとクライアントの文字コード設定が異なっていると文字化けが発生する。

2.どのようにすれば文字化けは発生しないのか?

サーバとクライアントにおいて、文字コード変換が起こらないようにすればよい。

3.サーバとクライアントで文字コード変換が起こらないようにするには?

サーバの文字コード設定とクライアントの文字コード設定を同じにする。

4.サーバの文字コード設定とクライアントの文字コード設定を同じにする方法は?

大きくわけて2通りある。1つ目は、利用する文字コードを決定し、明示的にサーバの文字コードとクライアントの文字コードを設定すること。2つ目は、強制的にクライアントの文字コード設定をサーバの文字コード設定にあわせること。

5.サーバの文字コード設定の方法は?

mysqlの設定ファイルである my.cnf においてサーバ設定セクションである[mysqld]セクションにてdefault-character-setで文字コードを設定する。

[mysqld]
default-character-set=****

6.クライアントの文字コード設定の方法は?

mysqlの設定ファイルである my.cnf においてクライアント設定セクションである[client][mysql][mysqldump]セクションにてdefault-character-setで文字コードを設定する。

# クライアントアプリ (PHPなど) 使用時設定
[client]
default-character-set=****
# mysql (標準client) 使用時設定
# mysql (標準client) に対して [client] での設定を上書き
[mysql]
default-character-set=****
# mysqldump 使用時設定
# mysqldump に対して [client] での設定を上書き
[mysqldump]
default-character-set=****

[mysql] セクションと[mysqldump] セクションでの設定は、 [client] での設定を上書きするものだから、 [client] と同じ設定ならば必要ないともいえる。
ただし、この設定でクライアントの文字コードが設定完了になるためにはある条件がある。その条件とは、クライアントアプリ (PHPなど) がこの my.cnf での設定を読み込んでいることである。もし読み込んでいない場合は、読み込むようにクライアントアプリ (PHPなど) で設定する必要がある。

7.クライアントアプリ (PHPなど) で my.cnf の設定を読み込む方法は?

クライアントアプリ (PHPなど) 側での設定は、C、PHP、Perlなどプログラム言語によって設定方法が違うので、以下のサイトの 「my.cnf を読む」 という部分を参照して設定する。
クライアントアプリ毎のmy.cnf の読み込み方
・Cの場合

mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, “/etc/my.cnf”);
mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, “groupname”);

・PHPの場合

PHP version 4 の場合
読めない。[client] に書いても無駄。
http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib のパッチを当てる。
PHP version 5の場合
mysqli モジュールに、my.cnf を読む関数が用意されている。
mysqli_options(connection, MYSQLI_READ_DEFAULT_FILE, “/etc/my.cnf”);
mysqli_options(connection, MYSQLI_READ_DEFAULT_GROUP, “php”);

・Perlの場合

$dsn = “DBI:mysql:test;mysql_read_default_group=perl;mysql_read_default_file=/etc/my.cnf”;

ただし、使っているクライアントのバージョンなどによって上記の関数が使えない場合もあるが、そういったケースでは、実際のSQL文の前に、「SET NAMES ‘****’;」を使って文字コードを指定する方法があるが、セキュリティ的に「SET NAMES ‘****’;」は問題があるという指摘もある(このサイトを参照のこと)ので、
悩んだ場合は、MySQL5開拓団 日本語処理の鉄則 KLab株式会社の<図3:クライアント側文字コードの指定チャート>のチャートに従って自分に環境にふさわしいものを選ぶこと!

8.強制的にクライアントの文字コード設定をサーバの文字コード設定にあわせる方法は?

mysqlの設定ファイルである my.cnf においてサーバ設定セクションである[mysqld]セクションにてskip-character-set-client-handshake オプションを利用する。

[mysqld]
default-character-set=****
skip-character-set-client-handshake

こうすると、サーバ側(mysqld)で設定した文字コードをクライアント側(mysql、phpなど)でも強制的に使ってくれるようになる。マニュアルには以下のように記述されている。
MySQL 5.0 Reference Manual

Don’t ignore character set information sent by the client. To ignore client information and use the default server character set, use –skip-character-set-client-handshake; this makes MySQL behave like MySQL 4.0.

とのこと。

ざっとしたところは、こんなところかな。
本エントリを書くに当たって、以下のサイトがとても役にたち、多く引用させていただいた。(感謝!)
iandeth. – MySQL 4.1 日本語環境設定方法 (キャラクタセット設定方法)
MySQL5開拓団 日本語処理の鉄則 KLab株式会社
MySQLの実験/1.システム変数の参照と変更
ちなみに、よくわからないままインストールして、デフォルトキャラクターセットがlatin1になっており、クライアントアプリ(phpなど)やphpMyAdminで文字化けしてしまい、どうしていいかよくわからないという人にうまくいくかわからないけど参考までに、メモ。
デフォルトキャラクターセットがlatin1になっているmysqlのphpMyAdminにてエンコーディングなしで、対象のデータベースをエクスポートし、テキストファイルにエンコードの種類「欧文」で保存する(変換できない文字があるとかいろいろ言われるが全部無視!)。そして、保存したファイル内に記述されてているSQLの「DEFAULT CHARSET=latin1 」を 「 DEFAULT CHARSET=*** 」 に全置換する(***には、utf8やujisなど自分のクライアントアプリの文字コードを入れる)。そのファイルを、phpMyAdminにてさきほど指定した自分のクライアントアプリの文字コードを文字セットに指定してインポートしてみたら?(保証なし)

スポンサーリンク
レクタングル(大)広告
  • このエントリーをはてなブックマークに追加
スポンサーリンク
レクタングル(大)広告

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です