211
172

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Laravel5.4以上、MySQL5.7.7未満 でusersテーブルのマイグレーションを実行すると Syntax error が発生する

Last updated at Posted at 2017-02-10

はじめに

古い備忘録だが、いまだに定期的にアクセスがあるので全面的に加筆修正した。
PHPやLaravelは新しいバージョンに追従していても、MySQLのバージョンはいまだ5.5~5.6、という環境も多いのだろう。

※2023年追記:すでにLaravel5系、MySQL5.6系ともにサポートの切れたかなり古いバージョンとなっているので、なるべくバージョンアップにて解決することを推奨する。

前提

  • Laravel5.4以上
  • MySQL5.7.7未満

現象

上記環境のもとで、$ php artisan make:authで自動作成されるマイグレーションファイルに対し、
$ php artisan migrate を実行すると、以下のエラーが発生する。

[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))

[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes

原因

1. Laravel5.4から標準charasetがutf8mb4に変わった

標準charasetがutf8mb4となったことで1文字あたりの最大byte数が4bytesに増えた。

2. MySQL5.7.7未満ではユニーク制約を付けたカラムは最大767bytes

マイグレーションファイルにvarcharカラムの大きさを指定しなかった場合、varchar(255) のカラムが作成される。

 $table->string('email')->unique();

一方、MySQL5.7.7以前のバージョンでは、PRIMARY_KEYおよびUNIQUE_KEYを付けたカラムには最大767bytesまでしか入らない。
4bytes,255文字では767bytesを超えてしまう。これがエラーの原因。

対策

対策としては以下の3つが考えられる。

  1. MySQLのバージョンを最新にする
  2. 使用するcharasetをutf8mb4から変更する
  3. カラムの最大長を変更し、767bytes以上の文字列が入らないようにする

対策1:MySQLのバージョンを最新にする

特段の事情がなければベストの対応。MySQL5.6系のPremier Support期限は2018年2月に終了している。

対策2:使用するcharasetをutf8mb4から変更する

Laravel5.3まではcharsetの標準設定はUTF-8だった。
config/database.php よりcharsetを以下のように変更すれば、Laravel5.3以前と同じ挙動で使用することができる。
ただし、絵文字 :sushi: など、4バイトで表現される文字は使えなくなる。

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

対策3:カラムの最大長を変更し、767bytes以上の文字列が入らないようにする

varchar(191) のカラムを作成すれば、191 * 4 = 764bytesのため、エラーが発生しない。

//個別で指定する例
 $table->string('email', 191)->unique();

上記のようにカラムごと個別に最大長を指定してもよいが、
app\Providers\AppServiceProvider.php に以下の記載を追加することで、最大長未指定時のdefault値を変更することが可能である。

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

これでマイグレーションを実行すれば、正常に動作する。

参考URL

  1. https://laravel-news.com/laravel-5-4-key-too-long-error
  2. http://d.hatena.ne.jp/tanamon/20090930/1254332746
211
172
3

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
211
172

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?