こんばんは、Webプログラマの篠田です。
日の出が少しずつ早くなってきて、早起きが少しずつしやすくなりますが、まだまだ布団の魔力は強く勢いがないとなかなか出られずに苦戦しています。
今日は、あまり意識をしない絵文字とMySQLとの関係についてご紹介します。
普段通りにMySQLに絵文字を保存するとバグる
多くの参考書や、Webサイトでも紹介されるのがMySQLで、「CREATE DATABASE」を実行するときは、文字コードを「utf-8(utf8_general_ci)」にするというのが、鉄則としてかかれています。
私も、基本的にデータベースを作成するときは「utf-8(utf8_general_ci)」で作成をします。
しかし、扱う文字列の中に「絵文字」が含まれる可能性があるときに、「utf-8(utf8_general_ci)」で作ったデータベース及びテーブルに、「絵文字」を保存すると盛大にバグが発生してしまいます。
バグの実態
「utf-8(utf8_general_ci)」で作成したテーブルに、「絵文字」を保存するとどうなるでしょうか。
答え「絵文字が書かれているまでの文字列しか保存されない!!」
つまり、すべての文字列を保存することができないという状況になります。
「utf-8(utf8_general_ci)」で作成したテーブルに対して、絵文字を「INSERT / UPDATE」すること自体にエラーは発生しないので、実際のデータを確認しないと気づかないという罠があります。
バグの原因
原因は、「絵文字」の文字コードにあります。
普段、取り扱う文字列は「1〜2バイト文字」なので、「utf-8(utf8_general_ci)」で問題なく扱えます。
しかし、「絵文字」は「4バイト文字」となり、「utf-8(utf8_general_ci)」の扱えるバイト数ではなく、登録ができないという事態になります。
解決方法
解決法は、「4バイト文字が扱える文字コードにする」です。
ここで登場するのが、「4バイト文字」を扱える「utf-8mb4」という文字コードを利用します。
注意が必要なのは、この文字コードが扱えるMySQLのバージョンは「5.5以上」になります。
データベースを「utf8mb4」対応する
既に作成済みのデータベースを「utf8mb4」対応するのは下記のSQLを実行します。
1 |
ALTER DATABASE データベース名 DEFAULT CHARACTER SET utf8mb4; |
新規に作成する場合は下記のSQLを実行します。
1 |
CREATE DATABASE データベース名 DEFAULT CHARACTER SET utf8mb4; |
テーブルを「utf8mb4」対応する
既に作成済みのテーブルを「utf8mb4」対応するのは下記のSQLを実行します。
1 |
ALTER TABLE テーブル名 DEFAULT CHARACTER SET utf8mb4; |
新規に作成する場合は下記のSQLを実行します。
1 |
CREATE TABLE テーブル名(カラム設定) DEFAULT CHARACTER SET utf8mb4; |
カラムを「utf8mb4」対応する
既に作成済みのカラムを「utf8mb4」対応するのは下記のSQLを実行します。
1 |
ALTER TABLE テーブル名 MODIFY カラム名 型 CHARACTER SET utf8mb4 […]; |
実行するときの文字コードも注意
MySQLの各データベースやテーブルの文字コードを変更しても、実行するプログラム側の文字コードを変更しないと、意味がありません。
必ずPDO等で「mysql:dbname=データベース名;host=localhost;charset=utf8mb4」を実行して、MySQLの操作をしましょう。
気になる文字コード変換に伴う文字化け
通常、文字コードを途中で変更すると、既に登録済みの文字列が大変なことになる場合がありますが、「utf8mb4」は「utf8」の拡張にあたるので文字化けは、基本的に発生しません。
例外的に「ハハパパ問題」と「寿司=ビール問題」が発生するリスクがありますが、その件に関しては別の機会に、ご紹介したいと思います。
まとめ
最近は、TwitterもiPhoneなどの絵文字を扱えるようになり、ガラケー時代とは異なる絵文字習慣が定着してきています。
MySQLのバージョンもあがることで、こういった問題に対応していることを知っていくことで、開発力をアップしていきたいですね。
【PR】
ALAKIでは、PHP&MySQLを使ってのシステム開発に力を入れています!!
システム案件でお困りごとがありましたら、お気軽に下記までご連絡ください。お待ちしていますm(_ _)m
■Webシステムの詳しい内容
https://alaki.co.jp/service/system.html