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 外部キー制約の使用