RDS の mySQL で日本語が文字化けて困った時の対応方法
RDS に作成したDBで日本語を格納しようと思ったのですが、以下のように日本語が文字化けてしまいました。
mysql> select * from SeriesData; +----------+------------+ | SeriesID | SeriesName | +----------+------------+ | 0 | ??? | | 1 | ???? | +----------+------------+ 2 rows in set (0.00 sec)
調べてみると、RDSのパラメーターグループというものでDBで利用するキャラクターセットなどを設定できるようなのですが、新しくパラメータグループを作り
- character_set_client
- character_set_connection
- character_set_database
- character_set_results
- character_set_server
あたりを、utf8 に設定しても文字化けが治りませんでした。
どうもすでに作成されているDBに対してパラメターグループの設定を行っても"character_set_database"は、latin1 のまま変更されないようです。
色々と知識が不足していて、日本語対応に手こずってしまったので、軽くやったことをメモとして残しておこうと思います。
DB に設定されているパラメーターの確認
DBに設定されているパラメータは以下のように確認することができます。
mysql> show variables like 'character_set%'; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.6.27.R1/share/charsets/ | +--------------------------+-------------------------------------------+ 8 rows in set (0.01 sec)
ここで、"character_set_database" に latin1 が設定されていることがわかると思います。
テーブルに設定されているキャラクターセットの確認
すでに作成されているテーブルにもキャラクターセットの設定が行われているようです。
これは、以下のように確認することができます。
mysql> show create table SeriesData; +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | SeriesData | CREATE TABLE `SeriesData` ( `SeriesID` int(11) NOT NULL, `SeriesName` tinytext, PRIMARY KEY (`SeriesID`), UNIQUE KEY `SeriesID_UNIQUE` (`SeriesID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | +------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
ここでも、"CHARSET=latin1" のように latin1 が設定されていることがわかります。
グローバル設定のキャラクターセットの確認
それでは、DBの設定ではなくグローバルの設定も確認してみることにします。
mysql> show global variables like 'character%'; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.6.27.R1/share/charsets/ | +--------------------------+-------------------------------------------+ 8 rows in set (0.00 sec)
RDS のパラメーターグループで、utf8を設定したあとだったのでグローバルの設定は全てutf8 に設定されいることが確認できました。
DBを作成した時のキャラクターセットの確認
また、DBを作成した時のキャラクターセットも確認してみます。
mysql> show create database totsuka_dev; +-------------+------------------------------------------------------------------------+ | Database | Create Database | +-------------+------------------------------------------------------------------------+ | totsuka_dev | CREATE DATABASE `totsuka_dev` /*!40100 DEFAULT CHARACTER SET latin1 */ | +-------------+------------------------------------------------------------------------+ 1 row in set (0.00 sec)
"DEFAULT CHARACTER SET latin1" となっています。
これは、パラメーターグループの変更を行う前に CREATE DATABASE を行っているので、latin1 が設定されしまっているようです。
DB のキャラクターセットの再設定
DB に設定されてしまったキャラクターセットはパラメーターグループを変更しても切り替えることはできないため、以下のように直接再設定を行います。
mysql> ALTER DATABASE totsuka_dev default character set utf8; Query OK, 1 row affected (0.00 sec)
そして、DBの設定を次のように確認してみます。
mysql> show create database totsuka_dev; +-------------+----------------------------------------------------------------------+ | Database | Create Database | +-------------+----------------------------------------------------------------------+ | totsuka_dev | CREATE DATABASE `totsuka_dev` /*!40100 DEFAULT CHARACTER SET utf8 */ | +-------------+----------------------------------------------------------------------+ 1 row in set (0.00 sec)
"DEFAULT CHARACTER SET utf8" のように utf8 に切り替わったことが確認できました。
そして、パラメーターの方も確認してみると、
mysql> show variables like 'character%'; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.6.27.R1/share/charsets/ | +--------------------------+-------------------------------------------+ 8 rows in set (0.00 sec)
このように、utf8に変更されたことが確認できます。
この状態でテーブルを select してみると次のようになります。
mysql> select * from SeriesData; +----------+------------+ | SeriesID | SeriesName | +----------+------------+ | 0 | ??? | | 1 | ???? | +----------+------------+ 2 rows in set (0.01 sec)
これは、先ほど書いた通りテーブル側にもキャラクターセットの設定が行われているからでした。
テーブルの再作成
今回は、レコード数も少なかったのでテーブルを再作成することにしました。
mysql> drop table SeriesData; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE `totsuka_dev`.`SeriesData` ( -> `SeriesID` INT NOT NULL, -> `SeriesName` TEXT(20) NULL, -> PRIMARY KEY (`SeriesID`), -> UNIQUE INDEX `SeriesID_UNIQUE` (`SeriesID` ASC)); Query OK, 0 rows affected (0.03 sec)
これで、日本語を含むレコードを追加してみます。
mysql> insert into SeriesData (SeriesID, SeriesName) values (0, 'にほんご'); Query OK, 1 row affected (0.01 sec)
select してみると、日本語が設定できていることが確認できました。
mysql> select * from SeriesData; +----------+--------------+ | SeriesID | SeriesName | +----------+--------------+ | 0 | にほんご | +----------+--------------+ 1 row in set (0.00 sec)
おまけ(DBを新規作成した時の状態を確認してみる)
RDS のパラメーターグループのキャラクターセットにutf8が設定されている時に、DBを新規作成した時の挙動を確認しておきます。
すでにグローバルのパラメーターにutf8が設定されているので、何も考えずに CREATE DATABASE をしてみます。
mysql> create database jp_test; Query OK, 1 row affected (0.01 sec)
そして、作成したDBに切り替え、パラメータを確認してみると、
mysql> use jp_test; Database changed mysql> show variables like 'character_set%'; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.6.27.R1/share/charsets/ | +--------------------------+-------------------------------------------+ 8 rows in set (0.00 sec)
このように character_set_database に utf8 が設定されていることがわかります。
まとめ
RDS のインスタンスを作成するときに、パラメーターグループを適切に設定できていれば今回のようなキャラクターセットの再設定は不要になると思います。
AWS は、便利ですが色々と覚えることがあって大変ですね。
とにかく手を動かして見ながら覚えていくしかなさそうなので、がんばっていこうとおもいます。
参考
MySQLでcharacter_set_databaseがlatin1になってしまう問題の対応方法
なぜ文字化けが起きているのか、状況の確認を行いながら対応の手順を示してくれいます。
とても参考になりました。