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になってしまう問題の対応方法

なぜ文字化けが起きているのか、状況の確認を行いながら対応の手順を示してくれいます。
とても参考になりました。