RDSのデフォルトの設定のクラスタで、データベースとテーブルを特に文字コードを設定せずに作成した場合、
VARCHAR(文字列)型の列を作ってもそこに日本語などのマルチバイト文字を格納することはできません。
カラムか、テーブルか、データベース単位で設定してもいいのですが、パラメーターグループを使って設定する方法を紹介します。
Aurora(正確にはそれが互換性を持っているMySQL)では、文字コード(Character Set)と照合順序(Collation)をそれぞれ独立した設定として持っています。
照合順序というのはソート順やアルファベットの大文字小文字を同一視するかどうかといったルールのセットです。
文字コードは日本語を使いたいのであればUTF8を使えるように設定する必要がありますが、
歴史的な経緯により、MySQLのUTF8には、utf8とutf8mb4の2種類があります。
utf8には3バイトまでの文字しか含まれておらず、絵文字等の4バイト文字も使えるようにするためにはutf8mb4を設定する必要があります。
参考: 10.1.10.7 utf8mb4 文字セット (4 バイトの UTF-8 Unicode エンコーディング)
さて、とりあえず何も設定しなかった場合の設定を見ておきましょう。
MySQL [(none)]> SHOW VARIABLES LIKE 'char%';
+--------------------------+-------------------------------------------------------------------------+
| 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 | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/oscar-5.7.serverless_mysql_aurora.2.08.3.38.0/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.01 sec)
MySQL [(none)]> SHOW VARIABLES LIKE 'coll%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | utf8_general_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.01 sec)
character_set_client, character_set_connection, character_set_results
はデフォルトでは utf8 になっていますが、 character_set_database と、 character_set_server が、latin1 になっています。
絵文字含む日本語文字を使うためにはこれら5つをutf8mb4に設定する必要があります。
ここからがややこしいことなのですが、RDSのパラメーターグループではこの5つをそれぞれ設定できるようになっているのに、
character_set_client, character_set_connection, character_set_results にはそれが反映されません。
そして、 character_set_database には character_set_server に設定した値が入ります。
反映されない3つは、クライアント側で設定する必要があるようです。
また、collation の方も、 collation_connection には設定した値が反映されず、
collation_server に設定した値が、collation_server と collation_database に反映されます。
これを踏まえて設定していきます。まず、RDSのパラメーターグループには次のふたつを設定します。
character_set_server: utf8mb4
collation_database: utf8mb4_bin
この段階で、設定は次のようになります。
MySQL [(none)]> SHOW VARIABLES LIKE 'char%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/oscar-5.7.serverless_mysql_aurora.2.08.3.38.0/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.01 sec)
MySQL [(none)]> SHOW VARIABLES LIKE 'coll%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8mb4_bin |
| collation_server | utf8mb4_bin |
+----------------------+-----------------+
3 rows in set (0.00 sec)
次にクライアント側の設定です。
僕は、Amazon Linux 2 で標準のRDSになった、MariaDBを利用しています。
設定ファイルは、 /etc/my.cnf なのですが、
その中を見ると、 !includedir /etc/my.cnf.d となっていて、他のファイルを読み込んでいます。
/etc/my.cnf.d/client.cnf と言うファイルの中に、 [client]と言うセクションがあるのでそこに設定します。
$ sudo vim /etc/my.cnf.d/client.cnf
[client]
# 以下の1行を追加
default-character-set = utf8mb4
MySQL [(none)]> SHOW VARIABLES LIKE 'char%';
+--------------------------+-------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/oscar-5.7.serverless_mysql_aurora.2.08.3.38.0/share/charsets/ |
+--------------------------+-------------------------------------------------------------------------+
8 rows in set (0.00 sec)
MySQL [(none)]> SHOW VARIABLES LIKE 'coll%';
+----------------------+--------------------+
| Variable_name | Value |
+----------------------+--------------------+
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8mb4_bin |
| collation_server | utf8mb4_bin |
+----------------------+--------------------+
3 rows in set (0.01 sec)
これで、ほぼ設定できました。
実用上これで困ることなく使うことができると思います。
後1点, collation_connection の設定が utf8mb4_bin にならずに、 utf8mb4_general_ci になってしまうのですが、
どなたか collation_connection の設定を utf8mb4_bin にする方法をご存知の方がいらしたら教えていただけないでしょうか。
そのセッションに限った設定であれば、
SET collation_connection = utf8mb4_bin;
で設定できるのですが、接続を切ると元に戻ってしまいます。
また、
SET GLOBAL collation_connection = utf8mb4_bin;
は RDS では実行できないようです。
先述の通り、パラメーターグループで設定しても反映されません。
あまり困ることもないのですが、ここだけ設定がズレていて気持ち悪いので可能であればutf8mb4_binに揃えたいです。