- MySQL5.6までと5.7以降は“同じDB”ではない
- 最大の変化:SQLモードのデフォルト変更
- なぜアプリケーションが壊れるのか
- STRICTモードの影響
- 日付の扱いも変わる
- インデックスと最適化の変化
- 文字コードと照合順序
- 5.6と5.7の思想の違い
- ORMやフレームワークへの影響
- 移行時のチェックポイント
- 結局、何が起きているのか
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を更新する作業ではありません。
アプリケーションが本当に正しいデータを扱っていたかを確認する作業になります。
この差を理解していないと、バージョンアップは単なるアップデートでは終わりません。
それはシステムの設計思想を洗い出す作業になります。