Laravel5.4 + MySQL5.5.9 でusersテーブルのマイグレーション時に Syntax error

はじめに

初投稿&Gistの自分用メモ書きを公開しただけなので読みにくかったら申し訳ない。

前提

  • Laravel5.4
  • MySQL5.5.9
  • artisan make:authで作成されるusersテーブルで発生

現象

Laravel5.4を新規導入し、意気揚々とmigrationを叩いたら、
以下のようなエラー(例外)が出た。

[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. MySQLではユニーク制約を付けたカラムには767bytesまでしか入らない

MySQLではPRIMARY_KEYおよびUNIQUE_KEYを付けたカラムには最大767bytesまでしか入らないらしい。
ver5.7.7以降だと解消されている模様。

対策

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

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

今回は3を選択。

変更点

前提

Laravelではマイグレーション時にカラムの大きさを指定しなかった場合、
255文字まで入るように設定されている。
下記のマイグレーションを実行するとemail varchar(255)のテーブルが作成される。

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

このときのカラムの大きさを変更する。
すなわち、上記マイグレーション実行時にemail varchar(191)となるテーブルが作成されれば、
utf8mb4を使用していても767bytes以上の文字列が入ることはない。

実装

app\Providers\AppServiceProvider.php
に以下を追加する。

use Illuminate\Support\Facades\Schema;

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

これでemail varchar(191)となるテーブルが作成され、エラーが発生しなくなった。

データベースの定義が大きく変わるので、
すでに稼働中のシステムであればcharasetを変更したほうがいいと思う。

参考URL

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

1見れば正直この記事いらない気もする。
日本語記事的な需要があるのであれば、これからもたまに投稿したい。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.