MySQL8.0のデフォルト文字コード変更の影響

MySQL8.0で突然「文字コード問題」が消えた理由

MySQLを長く触っていると、ある時期から妙な感覚になります。
「最近、文字化けトラブルを聞かなくなった」と感じた人もいるはずです。

実はこれ、偶然ではありません。
MySQL8.0でデフォルト文字コードが変更されたことが大きく影響しています。

そしてこの変更は、単なる改善ではなく「仕様の転換」に近いものです。
新規開発では恩恵になりますが、既存システムでは逆に混乱の原因にもなっています。

何が変わったのか

MySQL5.7までのデフォルトは次の設定でした。

  • 文字コード:utf8
  • 照合順序:utf8_general_ci

一方、MySQL8.0ではこうなりました。

  • 文字コード:utf8mb4
  • 照合順序:utf8mb4_0900_ai_ci

つまり、最初から4バイトUTF-8が使われます。
絵文字を保存できる設定が標準になりました。

SHOW VARIABLES LIKE 'character_set_server';

このコマンドを実行すると、バージョンによる違いが確認できます。

なぜこれが大きな変更なのか

一見すると「絵文字が保存できるようになった」だけに見えます。
しかし影響はそれだけではありません。

MySQLのデフォルト設定は、テーブル作成時に暗黙的に使われます。

CREATE TABLE users (
  name VARCHAR(100)
);

このSQLは、文字コードを指定していません。
つまりサーバのデフォルトを継承します。

5.7では3バイトUTF-8、
8.0では4バイトUTF-8になります。

同じSQLでも、データベースの中身が変わります。

移行時に起きる典型的な問題

MySQL8.0へアップグレードした直後、次の問題がよく起きます。

  • アプリが接続できない
  • テストだけ通らない
  • インデックス作成エラー
  • UNIQUE制約違反

原因は多くの場合、文字コードの不一致です。

特に多いのが「古いテーブル + 新しい接続設定」です。

  • テーブル:utf8
  • 接続:utf8mb4

この状態でデータを書き込むと、変換が発生します。
そして次のエラーが出ます。

  • Incorrect string value

アプリのバグに見えますが、DBの仕様変更です。

COLLATIONも変わっている

見落とされがちですが、8.0では照合順序も変わりました。

utf8mb4_0900_ai_ci は新しいUnicodeルールに基づきます。
その結果、比較結果が変わります。

例えば次です。

  • ß と ss
  • 全角と半角
  • アクセント付き文字

5.7では別扱いだったものが、同一扱いになる場合があります。

そのため次の現象が起きます。

  • 重複エラーが出る
  • ソート順が変わる
  • JOIN結果が変わる

SQLを変えていないのに挙動が変わります。

なぜMySQLは変更したのか

背景は「SQL標準」と「Unicode」です。

旧来のutf8_general_ciは簡易比較でした。
高速ですが言語的に正確ではありません。

8.0はUnicodeの正式な照合規則に近づきました。
つまり、データベースとしての整合性を優先した変更です。

よくある誤解

「8.0にすれば文字コード問題は全部解決する」
これは半分だけ正しいです。

新規構築ではほぼ解決します。
しかし既存データには影響が出ます。

特に危険なのがバックアップのリストアです。
5.7のダンプを8.0に入れると、比較結果が変わる可能性があります。

アプリ側の想定とズレることがあります。

リスクと注意点

アップグレード前に確認すべき項目があります。

  • テーブル文字コード
  • カラム文字コード
  • 接続文字コード
  • COLLATION

これを確認せずに8.0へ移行すると、
「動くが挙動が変わる」状態になります。

このタイプの不具合は最も発見が遅れます。

さらにインデックス長の制限も影響します。
utf8mb4ではキー長が増えるため、旧設計では作成できないことがあります。

どう対応すべきか

単純なバージョンアップとして扱わないことが重要です。
文字コード移行として計画する必要があります。

具体的には次の順序が安全です。

  • 既存テーブルをutf8mb4へ変換
  • 接続設定を統一
  • テストデータを日本語・絵文字で確認
  • その後8.0へ移行

これを逆にすると原因調査が難しくなります。

この変更の本当の意味

MySQL8.0のデフォルト文字コード変更は、単なる便利機能ではありません。
「データベースは文字列を正しく扱うべき」という方向への転換です。

これまでのMySQLは「多少曖昧でも動く」設計でした。
8.0以降は「正しく比較する」設計に近づいています。

その結果、トラブルは減りますが、
曖昧な前提で動いていたシステムは動かなくなります。

つまり8.0は新しい機能が増えたというより、
データの扱い方の前提が変わったバージョンと考えると理解しやすいです。