3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MySQLで🍣が保存できない?utf8とutf8mb4の違いを実験

Last updated at Posted at 2025-06-21

はじめに:MySQLを触ってみたら絵文字でエラーが…

image.png

MySQLを初めて触ってみたとき、「とりあえず文字コードはutf8にしておけば大丈夫だろう」と思っていました。ところが、絵文字を含むデータを保存しようとすると謎のエラーが発生...。調べてみると、MySQLの「utf8」には思わぬ落とし穴があることが分かりました。

同じようにMySQLを始めたばかりの方向けに、実際にGoogle Colabで再現しながら、この問題を理解していきましょう。

MySQLでWebアプリケーションを開発していて、こんな経験はありませんか?

  • 🍣や😀などの絵文字を保存しようとしたらエラーが発生
  • 「utf8」という文字コードを指定しているのに、なぜか文字化けが起こる
  • 旧漢字や特殊な文字で予期しない問題が発生

実は、MySQLの「utf8」は完全なUTF-8ではありません。この記事では、Google Colabを使って実際にエラーを再現しながら、utf8utf8mb4の違いを理解していきましょう。

utf8utf8mb4 の違い

image.png

まず、基本的な違いを整理しておきます。

項目 utf8 utf8mb4
正式名称 UTF-8の3バイト版 UTF-8の4バイト版(真のUTF-8)
対応文字数 基本多言語面(BMP)のみ Unicode全体
バイト数 最大3バイト 最大4バイト
絵文字対応 ❌ 不可 ✅ 可能
旧漢字対応 ❌ 一部不可 ✅ 可能
推奨度 非推奨 推奨

重要なポイント:MySQLの「utf8」は歴史的な理由により、UTF-8の一部(3バイトまで)しか対応していません。現在ではutf8mb4が標準として推奨されています。

実行環境について

この記事の内容は、以下の環境で動作確認を行いました:

  • 実行環境:Google Colab(無料版)
  • MySQLバージョン:8(aptでインストール)
  • Pythonバージョン:3.10+
  • 使用ライブラリ:
    • mysql-connector-python
    • pandas

Google Colabで実験しよう!

実際に手を動かして確認してみましょう。Google Colabで以下のコードを実行すると、問題を再現できます。

前提:ColabでMySQL起動

!apt-get -y install mysql-server > /dev/null
!service mysql start
!mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';"

image.png

【失敗編】utf8テーブルに🍣をINSERTしてみる

まずはutf8でデータベースとテーブルを作成します:

%%bash
mysql -uroot -proot -e "
DROP DATABASE IF EXISTS utf8_db;
CREATE DATABASE utf8_db CHARACTER SET utf8 COLLATE utf8_general_ci;
USE utf8_db;
CREATE TABLE memo (
    id INT PRIMARY KEY AUTO_INCREMENT,
    content TEXT
) CHARACTER SET utf8 COLLATE utf8_general_ci;"

次に、絵文字を含むデータをINSERTしてみましょう:

%%bash
mysql -uroot -proot utf8_db -e "
INSERT INTO memo (content) VALUES ('寿司🍣が好きです');
"

結果:エラーが発生!

image.png

ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x8D\xA3...' for column 'content' at row 1

このエラーの意味は、「🍣」という絵文字が4バイトの文字であり、3バイトまでしか対応していないutf8では保存できないということです。

【成功編】utf8mb4テーブルなら🍣も保存できる

今度はutf8mb4でデータベースを作成してみましょう:

%%bash
mysql -uroot -proot -e "
DROP DATABASE IF EXISTS utf8mb4_db;
CREATE DATABASE utf8mb4_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
USE utf8mb4_db;
CREATE TABLE memo (
    id INT PRIMARY KEY AUTO_INCREMENT,
    content TEXT
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
INSERT INTO memo (content) VALUES ('寿司🍣が好きです');
"

image.png

今度はエラーが発生せず、正常にINSERTが完了します!

【表示確認】Python で接続・SELECT

Pythonから接続して、正しく保存されているかを確認してみましょう:

%pip install -q mysql-connector-python

import mysql.connector
import pandas as pd

conn = mysql.connector.connect(
    host="localhost",
    user="root",
    password="root",
    database="utf8mb4_db",
    charset="utf8mb4"
)

df = pd.read_sql("SELECT * FROM memo;", conn)
print(df)

image.png

結果:正しく「寿司🍣が好きです」が表示されます!

【応用編】接続側をutf8にしてSELECTすると文字化け

データベース側はutf8mb4でも、接続時の文字コード設定がutf8だと問題が起こります:

%%bash
mysql -uroot -proot utf8mb4_db << 'EOF'
SET NAMES utf8;
SELECT content FROM memo;
EOF
"

image.png

この場合、絵文字部分が文字化けしたり、正しく表示されない可能性があります。

よくある誤解とチェックポイント

MySQLにおける文字コード設定には、いくつかの誤解が存在します。たとえば、utf8という指定が完全なUTF-8だと思われがちですが、実際には最大3バイトまでの制限があり、絵文字など一部の文字を正しく扱えません。

また、文字化けはINSERT時だけでなく、SELECT時の接続設定(たとえば SET NAMES)が正しくない場合にも発生することがあります。さらに、「utf8mb4は特殊な用途向け」と誤解されがちですが、現在ではあらゆる用途においてutf8mb4を使用するのが推奨されています。

チェックポイント

以下の設定をすべてutf8mb4に統一することが重要です:

  1. データベース作成時

    CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
    
  2. テーブル作成時

    CREATE TABLE mytable (...) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
    
  3. 接続時(Python例)

    conn = mysql.connector.connect(
        ...,
        charset="utf8mb4"
    )
    
  4. MySQL設定ファイル(my.cnf)

    [mysql]
    default-character-set = utf8mb4
    
    [mysqld]
    character-set-server = utf8mb4
    

まとめ

image.png

MySQLで日本語や絵文字などを安全に扱うには、文字コードの選択が非常に重要です。MySQLのutf8は最大3バイトまでの文字しか扱えないため、絵文字や一部の旧漢字など、4バイトの文字を保存することができません。このため、より広範な文字に対応したutf8mb4の利用が現在では推奨されています。

データベース、テーブル、接続設定など、すべての箇所でutf8mb4を統一して使うことで、文字化けや保存エラーといったトラブルを防ぐことができます。

この記事で紹介したサンプルは、Google Colab上ですぐに試せる内容となっており、実際に手を動かすことで、文字コードに関する問題点を具体的に理解できるはずです。

絵文字や多言語対応が求められるシーンが増えている今、utf8mb4の採用は非常に有効な選択肢です。ただし、時代の流れとともに文字コードやMySQLの仕様も変化していく可能性があるため、最新のMySQL公式ドキュメントも確認することをおすすめします。

これからMySQLを使って新しいアプリケーションを開発する際には、安全で柔軟なデータベース設計を意識しつつ、utf8mb4の利用を前向きに検討してみてください。

参考情報

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?