laravelでmigrate機能はとても便利です。
ライブラリ全般に言えることではありますが、1からクエリを書かないので管理のしやすさが格段に上がります。
しかし、生成されたクエリにエラーが発生した場合は、生でクエリを作るのと勝手が違って戸惑う場面もあります。
さて、
今回は、外部キー制約を扱う際に発生しうるエラーと、その対応方法について触れます。
目次
イントロダクション
この記事で得られること
- migrate時の「Foreign key constraint is incorrectly formed」エラーの解消方法がわかる
環境
種類 | バージョン |
---|---|
laravel | 5.5 |
状況
例えば、users
テーブルにcode
というカラムを追加し、
mapping
というテーブルから、code
に対して外部キーを設定するとします。
その場合、次のように設定をしている可能性があります。
- users
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->integer('code'); $table->string('password')->nullable(); $table->rememberToken(); $table->timestamps(); }); }
- mapping
public function up() { Schema::create('mappings', function (Blueprint $table) { $table->increments('id'); $table->integer('code'); $table->foreign('code')->references('code')->on('users'); $table->timestamps(); }); }
実行結果
上記migrateファイルを用意した状態で、migrateを実行すると次のようなエラーが返ってきます。
$ php artisan migrate SQLSTATE[HY000]: General error: 1005 Can't create table `test`.`#sql-1_b` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `mappings` add constrain t `mappings_code_foreign` foreign key (`code`) references `users` (`code`))
原因
原因は2つあります。
データの型が適切ではない。
数字型で外部キーを設定する場合は、符号なしの整数型(unsignedInteger)で指定する必要があります。 前項の例では、外部キーの対象が、符号付きの整数型(integer)を選んでいるためです。
$table->integer('code');
データがユニークではない。
外部キーにする場合、対象のカラムは重複してはいけません。
対象のカラムにUNIQUE 制約に設定する必要があります。
解決方法
前項の例を参考に修正箇所について触れます。
外部キーを対象元、対象先の文字型を下記のように変えます。
- users
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('code')->unique(); $table->string('password')->nullable(); $table->rememberToken(); $table->timestamps(); }); }
- mapping
public function up() { Schema::create('mappings', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('code'); $table->foreign('code')->references('code')->on('users'); $table->timestamps(); }); }
参考サイト
- Laravelのmigrateについて
データベース:マイグレーション 5.5 Laravel - MySQLの外部キー制約について
MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.1.17.2 外部キー制約の使用