移行:外部キー制約を追加できません


207

Laravelで外部キーを作成しようとしていますが、使用してテーブルを移行するとartisan、次のエラーがスローされます。

[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign 
key (`user_id`) references `users` (`id`))     

私の移行コードは次のとおりです:

優先度移行ファイル

public function up()
{
    //
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id');
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    //
    Schema::drop('priorities');
}

ユーザー移行ファイル

public function up()
{
    //
    Schema::table('users', function($table)
    {
    $table->create();
    $table->increments('id');
    $table->string('email');
    $table->string('first_name');
    $table->string('password');
    $table->string('email_code');
    $table->string('time_created');
    $table->string('ip');
    $table->string('confirmed');
    $table->string('user_role');
    $table->string('salt');
    $table->string('last_login');

    $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    //
        Schemea::drop('users');
}

ユーザー、クライアント、プロジェクト、タスク、ステータス、優先度、タイプ、チームなど、作成する必要のあるテーブルがたくさんあるので、私が間違ったことについてどんなアイデアでも、今すぐ取得したいと思います。理想的には私は外部キー、i..eでこのデータを保持するテーブルを作成したいclients_projectproject_tasksなど

誰かが私が始めるのを手伝ってくれることを願っています。

回答:


357

2つのステップで追加します。署名も不要です。

public function up()
{
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id')->unsigned();
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });

   Schema::table('priorities', function($table) {
       $table->foreign('user_id')->references('id')->on('users');
   });

}

117
ありがとう、アントニオ!私にとって問題は、user_id列にunsigned()を追加することではなかったので、usersテーブルのid列のデータ型と一致しました。Laravelのincrements( 'id')関数は符号なし整数を作成するため、外部キー列も符号なしである必要があります。
ブラッドグリフィス

7
Schema::tableメソッドへの分離を除いて、符号なしの追加が役立ちました!ありがとう!
patrickjason91 2015年

4
私にとっても、IDを署名なしにすることではありませんでした。先端をありがとう。
Carl Weis、2016

6
解決策は@BradGriffithのコメントにあります。上記のように、私はまったく分離する必要はありません。それに応じて回答を更新した方がいいでしょう。
Matanya

11
$table->unsignedBigInteger('user_id')user.idが次の場合に使用しますbigIncrements
Maksim Ivanov

114

質問はすでに回答済みですが、これが他の誰かの役に立つことを願っています。

キーが元のテーブルに主キーとして存在する前に、最初に外部キーを含む移行テーブルを作成したため、このエラーが発生しました。移行は、実行後に生成されたファイル名が示すとおり、作成された順序で実行されますmigrate:make。例えば2014_05_10_165709_create_student_table.php

解決策は、外部キーを含むファイルの名前を、ここで推奨されている主キーを含むファイルよりも前の名前に変更することでした。http//forumsarchive.laravel.io/viewtopic.php?id = 10246

私も追加しなければならなかったと思います $table->engine = 'InnoDB';


4
移行ファイルの名前を変更して次のようなエラーが発生した後:ストリームを開けませんでした:そのようなファイルまたはディレクトリはありません(そして古い移行名が表示されています)実行する必要があります:composer dump-autoload
Stelian

14
$ table-> engine = 'InnoDB'; MySqlレベルで外部キーを強制するために必要です。デフォルトのlaravelエンジンはMyIsamであり、外部キーをサポートしていません。
フランソワ・ブルトン

2
これも私にとってはうまくいきました。しかし、これがこのように機能するのは少し奇妙に思えます。つまり、それは理にかなっていますが、手動でファイルの名前を変更し、プロセスで偽の日付を
思い付く

2
エラーが発生したためではなく、外部キーである列に誤った値を追加することができました。次に、InnoDBに関するコメントと回答を確認しました。これは知って良かった。みんなありがとう:)
SuperNOVA

2
移行を作成した順序は、移行時に引き続き重要です。私はこの問題に遭遇しましたが、これで解決しました。
mugabits 2017

60

Laravel ^ 5.8

Laravel 5.8以降、移行スタブはデフォルトでID列でbigIncrementsメソッドを使用します。以前は、ID列はincrementsメソッドを使用して作成されていました。

これはプロジェクトの既存のコードには影響しません。ただし、外部キー列は同じ型でなければならないことに注意してください。したがって、incrementsメソッドを使用して作成された列は、bigIncrementsメソッドを使用して作成された列を参照できません

出典:Migrations&bigIncrements


単純なロールベースのアプリケーションを構築していて、PIVOTテーブル"role_user"のuser_idを参照する必要があるとしましょう。

2019_05_05_112458_create_users_table.php

// ...

public function up()
{
    Schema::create('users', function (Blueprint $table) {

        $table->bigIncrements('id');

        $table->string('full_name');
        $table->string('email');
        $table->timestamps();
    });
}

2019_05_05_120634_create_role_user_pivot_table.php

// ...

public function up()
{
    Schema::create('role_user', function (Blueprint $table) {

        // this line throw QueryException "SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint..."
        // $table->integer('user_id')->unsigned()->index();

        $table->bigInteger('user_id')->unsigned()->index(); // this is working
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });
}

ご覧のとおり、アップグレードノートに記載されているように、外部キー列は同じタイプである必要があるため、コメント行はクエリ例外をスローします。したがって、前のキー(この例ではuser_id)を次のように変更する必要があります。BigIntegerのROLE_USERのテーブルまたは変更bigIncrementsに方法インクリメントのメソッドユーザーのテーブルやピボットテーブル内のコメント行を使用し、それはあなた次第です。


この問題を明確にできたと思います。


1
ありがとうございました。あなたは私の命を救いました。あなたの説明に従って、私はあなたが提案したように私の外部キーをbigIntegerに変更しました。 Schema::table('goal_objective', function (Blueprint $table) { $table->bigInteger('job_title_id')->after('target')->unsigned()->nullable(); $table->foreign('job_title_id')->references('id')->on('job_titles')->onDelete('set null'); } 出来た。ありがとうございました。
Bruce Tong

1
@BruceTong、お役に立ててよかったです。
chebaby

1
うん、これは最も適切な答えです。
Mohd Abdul Mujib

1
この回答は非常に役立ちます。
Karim Pazoki

1
ベストアンサー。ありがとう
VishalParkash

49

私の場合、問題はメインテーブルに既にレコードがあり、新しい列をNULLにしないように強制していたことでした。そのため、新しい列に-> nullable()を追加するとうまくいきました。質問の例では、次のようになります。

$table->integer('user_id')->unsigned()->nullable();

または:

$table->unsignedInteger('user_id')->nullable();

これが誰かに役立つことを願っています!


親テーブルの「id」列も署名されていない必要があることに注意してください。$ table-> increments( 'id');などの行を使用します。自動的にデフォルトでunsignedになります。
Colin Stadig 16

これでうまくいきました。親テーブルIDのデータ型をBigIncrementsからincrementsに変更しました。
Emmanuel Benson

22

私の場合、問題はusersテーブルの自動生成された移行が設定されていたことでした

...
$table->bigIncrements('id');
...

だから私は列のタイプを変更する必要がありました


$table->bigInteger('id');

外部キーを使用した移行を機能させるため。

これとララベル 5.8.2


外部キー列は、参照する列と同じタイプである必要があるため
Daniele

9
これは私にとってはうまくいった$ table-> unsignedBigInteger( 'user_id'); laravel 5.8。*
Adam Winnipass

私は5.8でもこの問題がありました。これで修正されました!ありがとう!
Mike Sheward

長い夜から助けてくれた!
chq

19

私の場合、問題は移行のタイミングに関するものでした。移行を作成するときは、最初にベースの移行よりも子の移行を作成するときに注意してください。なぜなら、外部キーを持つ最初のベースマイグレーションを作成すると、子テーブルが検索され、例外をスローするテーブルがなくなるからです。

さらに:

移行を作成すると、最初にタイムスタンプが付けられます。あなたが移行を作成したとしましょう2015_08_19_075954_the_cats_time.php、それは次のようになり、このコードがあります

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class TheCatsTime extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('cat', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');  
            $table->date('date_of_birth');
            $table->integer('breed_id')->unsigned()->nullable(); 
        });

        Schema::table('cat', function($table) {
        $table->foreign('breed_id')->references('id')->on('breed');
      });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('cat');
    }
}

そして、ベーステーブルを作成した後、独自の作成日時スタンプを持つ子テーブルである別の移行の種類を作成します。コードは次のようになります。

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class BreedTime extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('breed', function (Blueprint $table) {
             $table->increments('id');    
             $table->string('name');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('breed');
    }
}

これら両方のテーブルが正しいようだが、あなたが実行したときにPHPの職人の移行を。最初にこの移行を作成し、ベーステーブルに外部キー制約があり、子テーブルを検索し、おそらく子テーブルが存在しないため、移行によって最初にデータベースにベーステーブルが作成されるため、例外がスローされます。例外..

そう:

最初に子テーブルの移行を作成します。

子の移行が作成された後にベーステーブルの移行を作成します。

PHPの職人が移行します。

うまくいきます


13

私の場合は、移行が手動で実行される順序を変更するだけなので、テーブルユーザーが最初に作成されます。

フォルダーdatabase / migrations /のマイグレーションファイル名の形式は次のとおりです:year_month_day_hhmmss_create_XXXX_table.php

テーブルの優先順位テーブルの作成日がユーザーの日付より後に設定されるように、作成ユーザーファイルの名前を変更するだけです(1秒後でも十分です)。


13

laravel 5.8では、users_tableはbigIncrements('id')主キーにデータ型を使用します。そのため、外部キー制約を参照する場合は、user_id列をunsignedBigInteger('user_id')タイプにする必要があります。


どうもありがとう、なぜ外部キーが例外を引き起こしているのかを理解するために1時間を費やしました
Ya Basha

10

Laravel 5.8を使用しても同じ問題が発生していましたlaravel docsを詳しく調べた後、さらにここにMigrations&bigIncrementsがあります。私がそれを解決した方法は、主キー「$ table-> bigIncrements( 'id')」を、テーブル「users」とその関連(私の場合はテーブル「role」)に関連するすべての単一のテーブルに追加することです。最後に、ロールをユーザー(多対多)に関連付けるための"$ table-> unsignedBigInteger"、つまりテーブル"role_user"がありました

1. Users table

    Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

2. Roles Table
    Schema::create('roles', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name')->unique();
        $table->string('display_name')->nullable();
        $table->string('description')->nullable();
        $table->timestamps();
    });

3. Table role_user
Schema::create('role_user', function (Blueprint $table) {
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('role_id');
            $table->foreign('user_id')->references('id')->on('users')
                ->onUpdate('cascade')->onDelete('cascade');
            $table->foreign('role_id')->references('id')->on('roles')
                ->onUpdate('cascade')->onDelete('cascade');
            $table->primary(['user_id', 'role_id']);
        });

9

私はlaravel 5.8でこの問題が発生しました。このコードは、ここでLaravelのドキュメントに示されているように、外部キーを追加する場所に修正しました。

$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

それから私は走った $ php artisan migrate:refresh

この構文はかなり冗長であるため、Laravelは、より優れた開発者エクスペリエンスを提供するための規則を使用する、より簡潔な追加のメソッドを提供します。上記の例は次のように書くことができます:

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
});

7

Laravel 5.3を使用しても同じ問題がありました。

解決策は、integer( 'name')-> unsigned()の代わりにunsignedIntegerを使用することでした。

これがうまくいきました

$table->unsignedInt('column_name');
$table->foreign('column_name')->references('id')->on('table_name');

これが機能した理由は、integer( 'name')-> unsignedを使用すると、テーブルに作成された列の長さが11になったが、unsigedInteger( 'name')を使用するとすると、列の長さが10になったためです。

長さ10は、列の長さが一致するようにLaravelを使用する場合の主キーの長さです。


投稿者を見つけたので、生のSQLをあきらめて実行しようとしていたことを感謝します。私は詳細laravel主キーの長さが10であることを余儀なくされている理由で読まなければならないとどのような理由がある場合は、なぜ整数で(「列」)やってます- >符号なし()unsigedInteger(「列」)と異なっている必要がありますが
アルノーブシュ

6

このエラーが発生したのは、私が作成しようとしたテーブルがInnoDBでしたが、関連付けようとした外部テーブルがMyISAMテーブルだったからです。


MyISAMは外部キー制約をサポートしていません。MyISAMに切り替えると、おそらく理由によりそこにあった外部キーが完全に無視されたため、おそらく機能しました。注意してください。
greggle138 2015

5

関連するテーブルが作成されない限り、リレーションを追加することはできません。Laravelは、移行ファイルの日付順に移行を実行します。したがって、2番目の移行ファイルに存在するテーブルとのリレーションを作成する場合、失敗します。

同じ問題に直面したため、すべての関係を指定するために、最後にもう1つ移行ファイルを作成しました。

Schema::table('properties', function(Blueprint $table) {
        $table->foreign('user')->references('id')->on('users')->onDelete('cascade');
        $table->foreign('area')->references('id')->on('areas')->onDelete('cascade');
        $table->foreign('city')->references('id')->on('cities')->onDelete('cascade');
        $table->foreign('type')->references('id')->on('property_types')->onDelete('cascade');
    });

    Schema::table('areas', function(Blueprint $table) {
        $table->foreign('city_id')->references('id')->on('cities')->onDelete('cascade');
    });

1
ファイルに何という名前を付けましたか?9999_99_99_999999_create_foreign_keys.php?
Iannazzi 2016

移行ファイル名に9999_99_99_99999を追加すると、ロールバック機能が台無しになるため、お勧めできません。
Maulik Gangani 2017

5

注意:Laravelが

$table->increments('id');

これはほとんどの移行で標準ですが、これにより符号なし整数フィールドが設定されます。したがって、別のテーブルからこのフィールドへの外部参照を作成するときは、参照元のテーブルで、フィールドをUnsignedIntegerに設定し、(私が想定している)UnsignedBigIntegerフィールドではないことを確認してください。

例:移行ファイル2018_12_12_123456_create_users_table.php内:

Schema::create('users', function (Blueprint $table){
    $table->increments('id');
    $table->string('name');
    $table->timestamps();

次に、移行ファイル2018_12_12_18000000_create_permissions_table.phpで、外部参照をユーザーに設定します。

Schema::create('permissions', function (Blueprint $table){
    $table->increments('id');
    $table->UnsignedInteger('user_id'); // UnsignedInteger = "increments" in users table
    $table->boolean('admin');
    $table->boolean('enabled');
    $table->timestamps();

    // set up relationship
    $table->foreign('user_id')->reference('id')->on('users')->onDelete('cascade');
}

5

このように書くべきです

public function up()
{
    Schema::create('transactions', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->float('amount', 11, 2);
        $table->enum('transaction type', ['debit', 'credit']);
        $table->bigInteger('customer_id')->unsigned();      
        $table->timestamps();                 
    });

    Schema::table('transactions', function($table) {
        $table->foreign('customer_id')
              ->references('id')->on('customers')
              ->onDelete('cascade');
    });     
}

外部キーフィールドは符号なしである必要があります。


署名されていないだけでなく、bigIncrements列を参照している場合はunsigedBigIntegerでなければなりません
gondwe

4

laravelで外部キー制約を追加するために、以下がうまくいきました:

  1. 次のように、外部キーになる列を作成します。

    $ table-> integer( 'column_name')-> unsigned();
  2. (1)の直後に制約行を追加する、つまり

    $ table-> integer( 'column_name')-> unsigned();
    $ table-> foreign( 'column_name')-> references( 'pk_of_other_table')-> on( 'other_table');

3

私はそれが古い質問であることを知っていますが、参照で作業している場合は、適切なサポートエンジンが定義されていることを確認してください。両方のテーブルにinnodbエンジンを設定し、参照列に同じデータ型を設定する

$table->engine = 'InnoDB';

2

最初の質問から数年後、laravel 5.1を使用してここでチャイムを鳴らしました。移行はすべて同じ日付コードでコンピューター生成されたのと同じエラーが発生しました。私はすべての提案されたソリューションを調べ、エラーの原因を見つけるためにリファクタリングしました。

次のララキャストとこれらの投稿を読むとき、別のスキーマ呼び出しを追加する必要がないことを除いて、正しい答えはビッキーズの答えに似ていると思います。テーブルをInnodbに設定する必要はありません。laravelがこれを実行していると思います。

移行のタイミングを正しく調整する必要があるだけです。つまり、外部キーが必要なテーブルのファイル名で日付コードを(後で)変更します。あるいは、またはさらに、外部キーを必要としないテーブルの日付コードを下げます。

日付コードを変更する利点は、移行コードが読みやすく、保守しやすくなることです。

これまでのところ、私のコードは、タイムコードを調整して、外部キーを必要とする移行をプッシュバックすることで機能しています。

しかし、私は何百ものテーブルを持っているので、最後には外部キーだけのための最後のテーブルが1つあります。物事を流すためだけに。私はそれらを正しいファイルにプルし、テストするときに日付コードを変更することを想定しています。

したがって、例:ファイル2016_01_18_999999_create_product_options_table。これには、productsテーブルを作成する必要があります。ファイル名を確認してください。

 public function up()
{
    Schema::create('product_options', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('product_attribute_id')->unsigned()->index();
        $table->integer('product_id')->unsigned()->index();
        $table->string('value', 40)->default('');
        $table->timestamps();
        //$table->foreign('product_id')->references('id')->on('products');
        $table->foreign('product_attribute_id')->references('id')->on('product_attributes');
        $table->foreign('product_id')->references('id')->on('products');


    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::drop('product_options');
}

製品表:これは最初にマイグレーションする必要があります。2015_01_18_000000_create_products_table

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');

        $table->string('style_number', 64)->default('');
        $table->string('title')->default('');
        $table->text('overview')->nullable();
        $table->text('description')->nullable();


        $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::drop('products');
}

最後に、問題を解決するために一時的に使用しているファイルの最後に、9999_99_99_999999_create_foreign_keys.phpという名前のモデルのテストを作成するときにリファクタリングします。これらのキーは、引き出したときにコメントされますが、要点はわかります。

    public function up()
    {
//        Schema::table('product_skus', function ($table) {
//            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
//    });

    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
//        Schema::table('product_skus', function ($table)
//        {
//            $table->dropForeign('product_skus_product_id_foreign');
//        });

2

とても簡単 !!!

最初に'priorities'移行ファイルを作成する場合、Laravel はテーブルが存在しない'priorities'ときに最初に実行され'users'ます。

存在しないテーブルにリレーションを追加する方法!

解決策:テーブルから 外部キーコードを引き出し ます。移行ファイルは次のようになります。'priorities'

ここに画像の説明を入力してください

新しい移行ファイルに追加します。ここにその名前がcreate_prioritiesForeignKey_tableあり、次のコードを追加します。

public function up()
{        
    Schema::table('priorities', function (Blueprint $table) {          
        $table->foreign('user_id')
              ->references('id')
              ->on('users');                        
    });
}

2

あなたの前列が前列のキー列の広い範囲を超えていることを確認してください

つまり、フォアキー(2番目のテーブル)は、ポンタープリンシパルキー(1番目のテーブル)と同じタイプでなければなりません。

ポインタプリンシパルキーは、署名されていないメソッドを追加する必要があります。

最初の移行テーブル:

$table->increments('column_name'); //is INTEGER and UNSIGNED

SECOND移行テーブル:

$table->integer('column_forein_name')->unsigned(); //this must be INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');

違いを見るための別の例

最初の移行テーブル:

$table->mediumIncrements('column_name'); //is MEDIUM-INTEGER and UNSIGNED

SECOND移行テーブル:

$table->mediumInteger('column_forein_name')->unsigned(); //this must be MEDIUM-INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');

MYSQL NUMERIC TYPESの表の範囲を見る


2

私が気づいたことの1つは、テーブルが外部キー制約とは異なるエンジンを使用する場合、機能しないことです。

たとえば、1つのテーブルが以下を使用する場合:

$table->engine = 'InnoDB';

そして他の用途

$table->engine = 'MyISAM';

エラーが発生します:

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint

次のように、テーブル作成の最後にInnoDBを追加するだけでこれを修正できます。

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedInteger('business_unit_id')->nullable();

        $table->string('name', 100);

        $table->foreign('business_unit_id')
                ->references('id')
                ->on('business_units')
                ->onDelete('cascade');

        $table->timestamps();
        $table->softDeletes();
        $table->engine = 'InnoDB'; # <=== see this line
    });
}

1

私の場合、文字列列の整数 id列を参照していました。私が変更され: user_id

$table->string('user_id')

に:

$table->integer('user_id')->unsigned();

それが誰かを助けることを願っています!


1

要点は、外部メソッドがALTER_TABLE既存のフィールドを外部キーにするために使用することです。したがって、外部キーを適用する前にテーブルタイプを定義する必要があります。ただし、別のSchema::呼び出しである必要はありません。次のように、作成内で両方を実行できます。

public function up()
{
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
}

また、タイプがuser_id外部キーと一致するようにunsignedに設定されていることにも注意してください。


1

整数列にブールパラメータを直接渡して、署名しないかどうかを指定できます。laravel 5.4では、次のコードで問題が解決しました。

        $table->integer('user_id', false, true);

ここで、2番目のパラメーターfalseは自動インクリメントではないことを表し、3番目のパラメーターtrueは符号なしであることを表します。外部キー制約は、同じ移行で保持することも、分離することもできます。両方で機能します。


1

初心者のための作業上記の解決策のいずれもチェックしない場合は、両方のIDが同じ型を持っている場合:両方があるinteger、またはその両方がありますbigInteger ...あなたはこのような何かを持つことができます:

メインテーブル(ユーザーなど)

$table->bigIncrements('id');

子テーブル(優先度など)

$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

ので、このクエリは失敗しますusers.idですBIG INTEGER一方priorities.user_idですINTEGER

この場合の正しいクエリは次のようになります。

$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

1

私の場合、コマンドを実行するまで機能しませんでした

composer dump-autoload

そうすれば、外部スキーマをcreateスキーマ内に残すことができます

public function up()
{
    //
     Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id');
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
 }

 /**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    //
    Schema::drop('priorities');
}

1

また、作成マイグレーションの順序になる場合もあります。最初にprioritiesテーブルを作成し、その後usersテーブルを作成した場合、それは間違ったものになります。ユーザーテーブルを探す最初の移行のため。そのため、移行の順序を変更する必要があります

app/database/migrations

ディレクトリ


1

私にとって、子テーブルが参照するテーブル列はインデックス付けされていませんでした。

Schema::create('schools', function (Blueprint $table) {
    $table->integer('dcid')->index()->unque();
    $table->integer('school_number')->index(); // The important thing is that this is indexed
    $table->string('name');
    $table->string('abbreviation');
    $table->integer('high_grade');
    $table->integer('low_grade');
    $table->timestamps();
    $table->primary('dcid');
});

Schema::create('students', function (Blueprint $table) {
      $table->increments('id');
      $table->integer('dcid')->index()->unique()->nullable();
      $table->unsignedInteger('student_number')->nullable();
      $table->integer('schoolid')->nullable();
      $table->foreign('schoolid')->references('school_number')->on('schools')->onDelete('set null');
      // ...
});

ひどい命名を無視してください、それは別のひどく設計されたシステムからのものです。


1

移行のシーケンスが原因で、このエラーが発生する場合があります。

Like UsersとOrderは2つのテーブルです

注文テーブルにはユーザーの元のキーがあります(注文テーブルが最初に移行する場合、移行中に外部キーと一致するユーザーがいないため問題が発生します)

解決策:注文の更新テーブルをユーザーの下に置くだけで更新できます

例:私の場合、教育テーブルと大学テーブル教育テーブル

public function up()
{
    Schema::create('doc_education', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('uni_id')->unsigned()->nullable();
        $table->timestamps();
    });
}

大学で

    Schema::create('doc_universties', function (Blueprint $table) {
        $table->increments('id');
        $table->string('uni_name');
        $table->string('location')->nullable();
        $table->timestamps();

        //
    });



Schema::table('doc_education', function(Blueprint $table) {
        $table->foreign('uni_id')->references('id')
        ->on('doc_universties')->onDelete('cascade');
    });

0

ここでの回答から欠落していると思うことが1つあります。間違っている場合は修正してください。ただし、外部キーはピボットテーブルにインデックスを付ける必要があります。少なくともmysqlではそうであるようです。

public function up()
{
    Schema::create('image_post', function (Blueprint $table) {
        $table->engine = 'InnoDB';
        $table->increments('id');
        $table->integer('image_id')->unsigned()->index();
        $table->integer('post_id')->unsigned()->index();
        $table->timestamps();
    });

    Schema::table('image_post', function($table) {
        $table->foreign('image_id')->references('id')->on('image')->onDelete('cascade');
        $table->foreign('post_id')->references('id')->on('post')->onDelete('cascade');
    });

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.