Laravel: Specified key was too long; max key length is 767 bytes
Laravelマイグレーション時にキー長エラーが発生する原因と解決策
概要
Laravel 5.4以降で新規プロジェクトを作成し、php artisan migrateを実行すると発生するエラー。MySQL 5.7.7未満またはMariaDB 10.2.2未満で、デフォルトの文字列長が長すぎることが原因です。
エラーメッセージ
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
(SQL: alter table `users` add unique `users_email_unique`(`email`))
原因
- 文字セットの変更: Laravel 5.4からデフォルト文字セットが
utf8mb4に変更された - インデックス長の制限: MySQL 5.7.7未満では、インデックスの最大長が767バイト
- 計算:
utf8mb4は1文字4バイト × 255文字 = 1020バイト(767を超過)
なぜ utf8mb4 なのか
utf8mb4は絵文字を含む全てのUnicode文字を保存できます。utf8(3バイト)では絵文字が保存できません。
解決策
1. AppServiceProviderでデフォルト文字列長を設定(推奨)
| |
なぜ191文字?
- 191 × 4バイト = 764バイト(767バイト以内)
2. MySQLをアップグレード
MySQL 5.7.7以上またはMariaDB 10.2.2以上にアップグレードすると、インデックスの最大長が3072バイトに拡張されます。
| |
3. config/database.phpで文字セットを変更(非推奨)
| |
注意: この方法だと絵文字が保存できなくなります。
4. マイグレーションで個別に長さを指定
| |
Laravel バージョン別の対応
| バージョン | デフォルト | 対応 |
|---|---|---|
| 5.3以前 | utf8 | 対応不要 |
| 5.4〜10.x | utf8mb4 | 解決策1を適用 |
| 11.x以降 | utf8mb4 | 解決策1を適用 |
よくある間違い
- 既存のマイグレーションファイルを編集せずに
defaultStringLengthだけ設定 migrate:fresh後に再度エラーが出る(AppServiceProviderの設定漏れ)- 本番環境のみMySQL古いバージョンで気づかない
参考リンク
関連エラー
関連エラー
PHP の他のエラー
この記事は役に立ちましたか?