LoginSignup
32
32

More than 5 years have passed since last update.

寿司ビール問題① 初心者→中級者へのSTEP20/25

Posted at

寿司ビール問題

はじめに

今回ご紹介するのは寿司ビール問題についてです。

寿司ビール問題とは

二つの絵文字、これが同じ文字扱いされてしまうこと。
つまり
🍣=🍺
別に他の絵文字でも同じです。
🐶=🐱
このように文字コードが原因でMySQLにて絵文字が同じ文字列扱いを受ける問題を寿司ビール問題と言います。(なんで寿司とビールになったかは不明)

そもそも文字コードってなんだっけ

「とりあえずutf-8使えばいんじゃね?」
って考えてました。でもそのとりあえずを払拭しなければ中級者にはなれないと思い、一度文字コードを振りかえってみる。

文字コード、調べていたら混乱したのでここではっきりさせておく。
まず文字コードとは文字集合、文字符号化方式の二つの要素のことを指す。(誰だこんな混乱するような言い回し作ったの)
文字集合
用いる文字の集合のこと、またその文字の対応する識別子のこと。Unicode,JIS X 0213などのこと。

文字符号化方式
上記の文字集合で得た識別子を符号化するときに用いる方式のこと。つまりエンコード。

こちらの記事がわかりやすいかも

んで、今回、🍣と🍺が同じ扱いを受ける原因なのはcharsetのutf8。
あ?charset?
またごちゃごちゃしそうですが、charsetとは「文字集合」と「エンコード」の両方を含んだ意味あいです。
MySQLのcharsetをutf8にすると、その場合Unicodeによって対応づけられた🍣と🍺の識別子を符号化して保存しようとすると、1文字1~3バイトしか対応しておらず、4バイト文字である絵文字は上手く保存できず文字化けして結局同じ文字扱いになってしまうのである。

対応

まずはcharsetutf8mb4にする。
utf8mb4は1~4バイトなので絵文字もOK。MySQLのcharsetutf8mb4にすればいいわけだが、ここで注意するのが、MySQLでは、サーバー、クライアント、サーバー/クライアント間、データベースごと、テーブルごと、カラムごとに指定できる。もちろん全て統一した方が良い。

次にcollationの設定です。
collationとはどの文字とどの文字を同値と扱うかという設定で、例えば大文字小文字は区別するのか、
以下のようになっている。

collation A:a 🍣:🍺  は:ば、ぱ:ハ や:ゃ 
general_ci = =
bin
unicode_ci = = = =
unicode_520_ci = = =

...理想的なのがない...(MySQL8では日本語に対応したcollationがあるがそれも微妙)
結局ここでトレードオフ的な感じになってしまう。

まとめ

そもそも絵文字を同値と扱わないで欲しいケースってなんなのだろう。気になる。
実は今回実装して試したかったのですが、RailsのDBをMySQLに移行しようとしたらハマってしまい。結局できませんでした...時間がないのでとりあえず概論的な感じです。明日までにできたら試してみます。

今回の内容はこちらのスライドがおすすめです。
https://www.slideshare.net/tmtm/mysql-2017-76154739?ref=http://tmtms.hatenablog.com/entry/2017/05/21/myna_nagano

参考にしたの

MySQLのencodingをutf8からutfmb4に変更して寿司ビール問題に対応する
https://techracho.bpsinc.jp/hachi8833/2016_08_25/25044#mysqlutf8mb4

[MySQL] 文字コード問題 -みんな大好き寿司ビール🍣🍺-
https://qiita.com/mamy1326/items/f516a3b7819a6a788dc3

ActiveRecordでデフォルトの照合順序を変更する
https://qiita.com/kamipo/items/d7863f0df24916005657

32
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
32