MySQL 5.6/5.7 世代で絵文字とかハハパパあたりに苦しめられた人多い問題。
- UTF8MB4 を利用する
innodb_file_format
innodb_large_prefix
はON
Barracuda
が取り込まれたので、項目が存在しなくなった- フレームワークなどからのアクセスで時刻補正されるとは限らないので、DB 内の時間も Tokyo にする
- ActiveRecord 経由で操作してて、 lib/task くコ:彡のタスクを実行するとたまに死ぬので、面倒を見てあげようネ!
innodb_per_table
5.6/5.7 でも書いたけどデフォルト 1
だったので変更しなくてオッケー!
collation わからなさすぎ問題
collation は用途によって速度やマッチング問題などあるため、最低限に含めていません。 悩んでいる理由は以下。
困ったら MySQL8 時代はとりあえずデフォルトでいいよ。 最悪 ALTER すりゃいいし(ざる)。
utf8mb4_0900_ai_ci
デフォルトが utf8mb4_0900_ai_cI
になったため、とりあえず何も考えずに構築して latin1
からのマルチバイト全滅はなくなりました。 しかしこの _ai_ci
が曲者です。
_ai
- アクセント イン センシティブ
- アクセント違い、つまり半濁音とか濁音の無視ってことだと理解しています。 「は」と「ぱ」がイコールになり、ハハパパ問題再燃するはず。
_ci
- ケース イン センシティブ
- 文字サイズ違い、つまり大小を無視することだと理解しています。 「あいうえお」と「ぁぃぅぇぉ」がイコールになる、死滅したコギャルか文末に emoji 乱射するぉじさんくらいしか得をしない。
utf8mb4_ja_0900_as_cs
こちらは 8.0.1 で追加されたジャップ向けの嬉しいヤツ。 上記とは違いセンシティブ解釈なので、違いを無視しません(別物とみなす)。 以下の記事で説明されているのが日本語の人にはわかりやすいでしょう!
utf8mb4_bin
以下うろ覚えなので間違ってたら直します。
utf8mb4_ja_0900_as_cs
で解決じゃないの? と思われるでしょうが、これカタカナの全角半角をイコールにできる、という事にお気づきでしょうか。 つまり同じ理論でいくと、 A = A
が成立してしまうはずなんすね。
これは例えば、ユーザ登録画面で「登録時の住所や電話番号、全角半角切り替えるのめんどくせえ頃すぞ!」というご意見に対して、判別を MySQL にまかせてしまえるのでストレスが下がりますね。
(上記ブログにもあったけど、旧字体と新字体のマッピングについてはその……みたいなアレ、また別の話題なのでそのうち。)
また、ユニーク制限したい(ユニークであるはず)ログイン ID やメールアドレスなどは、個別にバリデーションで制限されているので大丈夫! と思うかもしれませんが、コード管理の都合や古いシステムのアップグレードなどですり抜けてくる可能性はゼロではないはずです。
気をつけようね! ですめば良いのですが、だいたい済まない事例が発生するので、個人的にはいっそ utf8mb4_bin
で、入力されてきた文字は全部違うものとみなしたほうが安全だと思っています。
速度は犠牲になるので、ユーザ側フロント部に強力なバリデーションがあれば……とは思ってもいます。 良し悪しですね。