LaravelやRailsでcollationをデフォルトのまま使ってしまった時は

utf8mb4_unicode_ciは「か」と「が」を同一視したりするので、日本語アプリケーションでは使えない。のだが、日本語対応が十分でないフレームワークなどではよくデフォルトになっている。

最初からちゃんと設定しておけばいいのだが、忘れたまましばらくしてから気付いてしまった場合は、修正が面倒だ。

MySQLでは、collationはデータベースのデフォルト、テーブルのデフォルト、カラムのデフォルトと3段階ある。そのうちデータベースのデフォルトについては多分フレームワーク側では関与していないので、今回は無視する。

テーブルとカラムのデフォルトは、以下のクエリで変更できる。

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

-- あるいは、utf8mb4のデフォルトのcollationはutf8mb4_general_ciなので、これでも同じ
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4;

残念ながらMySQLではALTER TABLEを繰り返して実行することはできないので、データベース内のすべてのテーブルを一括で変更するには、シェルスクリプトなりで対応するしかない。zshならこんな感じとか。

for table in $(mysql DATABASE -BNe 'show tables')
mysql DATABASE -e "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"

注意

ALTER TABLE ... CONVERT TO CHARACTER SET ...は、今回のようにCHARACTER SETを変更しないような場合はおそらく安全に使えるが、CHARACTER SETを変更する場合は文字列系のカラムのサイズが変更されてしまう場合がある。

データ型が VARCHAR か、またはいずれかの TEXT 型であるカラムに対して、CONVERT TO CHARACTER SET は、新しいカラムが確実に元のカラムと同じ数の文字を格納できる十分な長さになるように、必要に応じてデータ型を変更します。 https://dev.mysql.com/doc/refman/5.6/ja/alter-table.html

特にフレームワークでmigratorを使っているような場合致命的な問題が発生しかねないので気をつけた方がいいかもしれない。