MySQL5.6と5.7は別物と言える理由

MySQL5.6までと5.7以降は“同じDB”ではない

MySQL5.6で動いていたアプリケーションは、5.7に上げた瞬間に壊れることがあります。
しかもレアケースではなく、業務システムではかなりの確率で発生します。

「メジャーバージョンが1つ上がっただけ」と思われがちですが、実際にはそれ以上の変化が起きています。
体感としては、マイナーバージョンアップではなくデータベース製品の入れ替えに近い挙動です。

重要なのは性能でも新機能でもありません。
SQLの解釈ルールが変わったことです。

最大の変化:SQLモードのデフォルト変更

MySQL5.7から、SQLモードの初期設定が大きく変わりました。
特に影響が大きいのが ONLY_FULL_GROUP_BY です。

5.6では、次のSQLは問題なく動きました。

SELECT user_id, name
FROM users
GROUP BY user_id;

このSQLは標準SQLとしては不正です。
GROUP BYしているのに、nameが集約されていないからです。

5.6は「適当な1行」を返しました。
しかし5.7ではエラーになります。

つまり5.7は、SQLを「解釈するDB」から「検証するDB」に変わりました。

なぜアプリケーションが壊れるのか

多くの既存システムは、この“曖昧なGROUP BY”を前提に書かれています。
特に次のような処理で使われます。

  • 最新データの取得
  • 一覧画面の代表行表示
  • ステータスの判定

開発者はMAXやORDER BYと組み合わせて正しく動いていると思っていますが、実際には偶然成立していただけです。

5.7では偶然が許されません。
そのため、SQL例外として停止します。

STRICTモードの影響

5.7ではSTRICT_TRANS_TABLESも有効になります。
これにより「今まで入っていたデータ」が入らなくなります。

典型例です。

INSERT INTO members (age) VALUES ('abc');

5.6では0として保存されました。
5.7ではエラーになります。

つまり5.6は「補正するDB」、5.7は「拒否するDB」です。

日付の扱いも変わる

古いMySQLでよく使われていたのがゼロ日付です。

INSERT INTO orders (created_at) VALUES ('0000-00-00');

5.6では通ります。
5.7では拒否されます。

この仕様変更は地味に大きく、次の機能が止まります。

  • 仮登録ユーザー
  • 未確定注文
  • 下書きデータ

原因が分かるまで、アプリケーションのバグと誤解されがちです。

インデックスと最適化の変化

5.7ではオプティマイザも強化されました。
これは良い変化ですが、副作用もあります。

  • 実行計画が変わる
  • ORDER BYの結果順が変わる
  • 取得レコードが変わる

5.6ではたまたま並んでいた順序に依存したコードが壊れます。
特に「ORDER BYを書いていない一覧表示」は危険です。

DBは順序を保証しません。
5.7はその事実が表面化するだけです。

文字コードと照合順序

5.7では照合順序の扱いも厳密になりました。
比較結果が変わるケースがあります。

例えば、大文字小文字の比較や全角半角の扱いです。
検索結果が増減することがあります。

アプリ側から見ると「検索バグ」に見えますが、DBの比較ルールの違いです。

5.6と5.7の思想の違い

5.6までのMySQLは「Web開発者向けのDB」でした。
動かすことが最優先でした。

5.7以降は「RDBMS」としての整合性を重視します。
SQL標準への準拠が強くなりました。

この違いが意味するものは大きいです。

5.6

  • 曖昧なSQLでも動く
  • 入力値を補正する
  • 開発者に優しい

5.7

  • 不正SQLを拒否
  • 不正データを拒否
  • データに正直

ORMやフレームワークへの影響

5.6時代のORM設定のまま5.7に接続すると、例外が多発します。
特に次の機能が影響を受けます。

  • ページング
  • 集計
  • 管理画面

ORMが壊れたのではありません。
DBの前提が変わったのです。

移行時のチェックポイント

バージョンアップ前に確認すべき項目です。

  • GROUP BYを使ったSQL
  • ORDER BYなしのSELECT
  • ゼロ日付
  • 型不一致INSERT
  • NULL処理

これらがあるほど移行コストは増えます。

結局、何が起きているのか

MySQL5.6から5.7への変化は、単なる性能向上ではありません。
DBの役割そのものが変わっています。

5.6はアプリケーションの補助ツールでした。
5.7はデータの整合性を守るシステムです。

だから壊れます。
アプリケーションが悪いわけではありません。

アプリケーションは、5.6の「寛容な挙動」に合わせて設計されているからです。

5.7への移行とは、DBを更新する作業ではありません。
アプリケーションが本当に正しいデータを扱っていたかを確認する作業になります。

この差を理解していないと、バージョンアップは単なるアップデートでは終わりません。
それはシステムの設計思想を洗い出す作業になります。