“1071 Specified key was too long; max key length is 767 bytes” Error – Laravel –

Laravelのmigrateで以下のエラーが出るときがあります。Lolipopのサーバーでは必ず出ます。(2021-08-01時点)
原因は、Laravel5.4から標準charasetがutf8mb4に変わったというものです。標準charasetがutf8mb4となったことで1文字あたりの最大byte数が4bytesに増えた。つまり絵文字が使えるcharaset設定になっています。
解決方法としてはMySQL5.7.7未満ではユニーク制約を付けたカラムは最大767bytesのためMySQLを最新にするのがベストプラクティスです。

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `password_resets` add index `password_resets_email_index`(`email`))

いくつかの事情でMySQLのアップグレードができない場合は絵文字を使うという選択肢を捨ててMySQL5.7.7未満のバージョンを使うことになります。
マイグレーションファイルにvarcharカラムの大きさを指定しなかった場合、varchar(255) のカラムが作成されることになります。下記のようなマイグレーションの関数はvarchar(255)を生成しています。4bytes,255文字では767bytesを超えてしまう。これがエラーの原因。

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

ですので、マイグレーションファイルのこの部分を明示的に、

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

191文字の長さで設定するとエラーが出なくなります。
しかしこの方法はマイグレーションファイルが作成されるたび(新しいテーブルを作成するたび)に注意を払わなくてはならないので、明示的にこの長さを初期動作で指定して上げるほうがよいです。app/Providers/AppServiceProvider.phpを以下のように修正します。

...
use Illuminate\Support\Facades\Schema; // 追加
...
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191); //追加
    }

これでmigrationを実行してもエラーは出なくなります。
MySQLをアップグレードできるタイミングが来たら、上記ファイルを元に戻して、DBを再接続してあげればOKです。


  • News

  • Categories

  • Tags

  • Archives

  • Page index