마이그레이션 : 외래 키 제약 조건을 추가 할 수 없습니다


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

누군가 나를 도울 수 있기를 바랍니다.

답변:


356

두 단계로 추가하고 서명하지 않은 것이 좋습니다.

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 ()를 추가하지 않아서 사용자 테이블의 id 열의 데이터 유형과 일치하지 않았습니다. Laravel의 increments ( 'id') 함수는 부호없는 정수를 생성하므로 외래 키 열도 부호가 없어야합니다.
Brad Griffith

7
Schema::table메소드 를 분리하는 것 외에도 서명되지 않은 것을 추가 하는 것이 도움이되었습니다! 감사!
patrickjason91

4
나에게도 ID를 서명하지 않았습니다. 팁 고마워.
Carl Weis

6
해결책은 @BradGriffith의 의견에 있습니다. 위에서 언급했듯이 전혀 분리 할 필요가 없습니다. 그에 따라 답변을 업데이트하는 것이 좋습니다.
Matanya

11
사용 $table->unsignedBigInteger('user_id')하여 user.id 경우bigIncrements
막심 이바노프

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 수준에서 외래 키를 적용해야합니다. 기본 라 라벨 엔진은 MyIsam으로 외래 키를 지원하지 않습니다!
François Breton

2
이것은 나에게도 도움이되었습니다. 감사합니다. 그러나 이것이 이런 식으로 작동한다는 것은 조금 이상하게 보입니다. 나는 그 말이 의미하지만, 수동으로 파일 이름을 변경하는 과정에서 가짜 날짜와 함께 오는 이외의 마이그레이션 실행 순서를 지정하는 방법이 있어야한다
allisius

2
오류가 발생하여 여기에 오지 않았지만 외래 키 인 열에 잘못된 값을 추가 할 수있었습니다. 그런 다음 InnoDB에 대한 의견과 답변을 보았습니다. 알아두면 좋았습니다. 감사합니다 사람 :)
SuperNOVA

2
마이그레이션을 생성 한 순서는 마이그레이션시 여전히 중요합니다. 이 문제가 발생했지만 문제가 해결되었습니다.
mugabits

60

라 라벨 ^ 5.8

Laravel 5.8 부터 마이그레이션 스텁은 기본적으로 ID 열에 bigIncrements 메소드를 사용합니다. 이전에는 증가 법을 사용하여 ID 열을 만들었습니다.

프로젝트의 기존 코드에는 영향을 미치지 않습니다. 그러나 외래 키 열의 유형이 같아야합니다 . 따라서 증가 방법 사용하여 작성된 열은 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 2016 년

1
그렇습니다. 이것이 가장 관련있는 답변입니다.
Mohd Abdul Mujib 2

1
이 답변은 매우 유용합니다.
Karim Pazoki

1
최고의 답변. 감사합니다
VishalParkash

49

필자의 경우 문제는 기본 테이블에 이미 레코드가 있고 새 열이 NULL이 아니어야한다는 것입니다. 따라서 새 열에-> nullable ()을 추가하면 트릭을 수행했습니다. 질문의 예에서 다음과 같습니다.

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

또는:

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

이것이 누군가를 돕기를 바랍니다!


부모 테이블의 'id'열도 부호가 없어야합니다! $ table-> increments ( 'id')와 같은 줄 사용하기; 기본적으로 자동으로 서명되지 않습니다.
Colin Stadig

이것은 나를 위해 일했습니다. 부모 테이블 ID의 데이터 유형을 BigIncrements에서 증분으로 변경했습니다.
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 artisan migrate 를 실행할 때 . 이 마이그레이션을 먼저 생성하고 기본 테이블에 외래 키 제약 조건이 있으므로 하위 테이블을 찾고 하위 테이블이 존재하지 않기 때문에 마이그레이션에서 데이터베이스에 기본 테이블을 먼저 생성하기 때문에 예외가 발생합니다. 예외..

그래서:

먼저 하위 테이블 마이그레이션을 작성하십시오.

하위 마이그레이션이 작성된 후 기본 테이블 마이그레이션을 작성하십시오.

PHP 장인 마이그레이션.

작동합니다


13

내 경우에는 테이블 마이그레이션이 먼저 생성되도록 마이그레이션이 수동으로 실행되는 순서를 변경합니다.

폴더 데이터베이스 / 마이그레이션 / 마이그레이션 파일 이름은 year_month_day_hhmmss_create_XXXX_table.php 형식입니다.

테이블 우선 순위 테이블의 생성 날짜가 사용자 날짜보다 늦게 설정되도록 사용자 파일 생성 이름을 바꾸십시오 (1 초 후에도 충분 함).


13

laravel 5.8에서 users_table은 bigIncrements('id')기본 키에 데이터 유형을 사용 합니다. 따라서 외래 키 제약 조건을 참조하려면 user_id열을 unsignedBigInteger('user_id')입력 해야 합니다.


정말 감사합니다, 나는 외래 키가 예외를 일으키는 이유를 알아 내려고 한 시간을 보냈습니다
Ya Basha

10

Laravel 5.8을 사용하여 동일한 문제가 발생했습니다 . laravel 문서를 자세히 살펴본 후 여기에서 Migrations & bigIncrements를 참조하십시오 . 내가 해결 한 방법은 기본 테이블 "$ table-> bigIncrements ( 'id')" 를 테이블 "users" 및 해당 연결과 관련된 모든 단일 테이블 ( 제 경우에는 "role")에 추가하는 것 입니다. 마지막으로 역할을 사용자 (다 대다 ), 즉 "role_user" 테이블에 연결하기위한 "$ table-> unsignedBigInteger" 가있었습니다 .

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 documentation에 표시된 것처럼이 코드를 외래 키를 추가하는 곳으로 수정했습니다.

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

그때 나는 달렸다 $ php artisan migrate:refresh

이 구문은 다소 장황하므로 Laravel은 더 나은 개발자 경험을 제공하기 위해 규칙을 사용하는 추가의 terter 메소드를 제공합니다. 위의 예는 다음과 같이 작성 될 수 있습니다.

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 ( '열') 달라야을
아르노 부 cho

6

이 오류는 내가 만들려고하는 테이블이 InnoDB 였을 때-MyISAM 테이블과 관련이 있었기 때문에 외래 테이블이기 때문에 나에게 발생했습니다!


MyISAM은 외래 키 제약 조건을 지원하지 않습니다. MyISAM으로 전환하면 이유가있을 수있는 외래 키를 완전히 무시했기 때문에 효과가 있었을 것입니다. 조심해.
greggle138

5

관련 테이블이 작성되지 않으면 관계를 추가 할 수 없습니다. Laravel은 마이그레이션 파일 날짜별로 마이그레이션 순서를 실행합니다. 따라서 두 번째 마이그레이션 파일에 존재하는 테이블과의 관계를 만들려면 실패합니다.

나는 같은 문제에 직면하여 결국 모든 관계를 지정하기 위해 하나 이상의 마이그레이션 파일을 작성했습니다.

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

마이그레이션 파일 이름에 9999_99_99_99999를 추가하면 롤백 기능이 손상되므로 좋지 않습니다.
Maulik Gangani

5

주의 : Laravel이 다음을 사용하여 테이블을 설정할 때

$table->increments('id');

대부분의 마이그레이션에서 표준이며 서명되지 않은 정수 필드가 설정됩니다. 따라서 다른 테이블에서이 필드에 대한 외부 참조를 작성할 때 참조 테이블에서 필드를 UnsignedInteger로 설정하고 UnsignedBigInteger 필드가 아닌 필드를 UnsignedInteger로 설정했는지 확인하십시오.

예를 들어 : 마이그레이션 파일 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-> 정수 ( 'column_name')-> unsigned ();
  2. (1) 바로 뒤에 제한선 추가

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

3

나는 오래된 질문이라는 것을 알고 있지만 적절한 작업 엔진이 참조로 작업하고 있는지 확인하십시오. 테이블에 대해 innodb 엔진을 설정하고 참조 열에 대해 동일한 데이터 유형을 설정하십시오.

$table->engine = 'InnoDB';

2

laravel 5.1을 사용하여 원래 질문 후 몇 년 동안 여기에서 Chiming하면 마이그레이션이 모두 동일한 날짜 코드로 생성 된 컴퓨터와 동일한 오류가 발생했습니다. 제안 된 모든 솔루션을 살펴본 다음 리팩터링하여 오류 소스를 찾습니다.

다음의 라라 캐스트와이 게시물을 읽을 때 정답은 Vickies 답변과 비슷하지만 별도의 스키마 호출을 추가 할 필요가 없다는 점을 제외하고는 그렇습니다. 테이블을 Innodb로 설정할 필요가 없습니다. 라 라벨이 지금하고 있다고 가정합니다.

마이그레이션은 단순히 정확하게 시간을 정하면되므로 외래 키가 필요한 테이블의 파일 이름에서 날짜 코드를 나중에 수정해야합니다. 또는 외래 키가 필요없는 테이블의 날짜 코드를 낮추십시오.

날짜 코드를 수정하면 마이그레이션 코드를보다 쉽게 ​​읽고 관리 할 수 ​​있다는 이점이 있습니다.

지금까지 내 코드는 타임 코드를 조정하여 외래 키가 필요한 마이그레이션을 다시 푸시하여 작동합니다.

그러나 나는 수백 개의 테이블을 가지고 있기 때문에 결국에는 외래 키에 대한 마지막 테이블이 하나 있습니다. 그냥 흐르는 것. 올바른 파일로 가져 와서 테스트 할 때 날짜 코드를 수정한다고 가정합니다.

예를 들어, 2016_01_18_999999_create_product_options_table 파일입니다. 제품 테이블을 만들어야합니다. 파일 이름을보십시오.

 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'마이그레이션 파일을 처음 만들면 테이블이 존재하지 않는 'priorities'동안 Laravel이 먼저 실행 'users'됩니다.

존재하지 않는 테이블에 관계를 추가하는 방법!.

해결 방법 : 테이블 에서 외래 키 코드꺼내십시오 . 마이그레이션 파일은 다음과 같아야합니다.'priorities'

여기에 이미지 설명을 입력하십시오

새 마이그레이션 파일에 create_prioritiesForeignKey_table추가 하십시오. 여기에서 이름은 다음 코드를 추가하십시오.

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

2

앞 기둥이 앞 기둥 키의 넓은 범위를 넘어서 있는지 확인하십시오

나는 당신의 foreingkey (두 번째 표)는 당신의 ponter pricipal key와 같은 유형이어야합니다 (첫 번째 표)

포인터 주요 키는 서명되지 않은 메소드를 추가해야합니다.

FIRST 마이그레이션 테이블에서 :

$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');

차이를 보는 다른 예

FIRST 마이그레이션 테이블에서 :

$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 숫자 유형 테이블 범위보기


2

내가 주목 한 것은 테이블이 외래 키 제약 조건과 다른 엔진을 사용하면 작동하지 않는다는 것입니다.

예를 들어 한 테이블에서 다음을 사용하는 경우 :

$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::전화를 걸 필요는 없습니다 . 다음과 같이 create 내에서 두 가지를 모두 수행 할 수 있습니다.

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외래 키와 일치하도록 유형이 부호없는 것으로 설정되어 있습니다.


1

부울 매개 변수를 정수 열에 직접 전달하여 부호가 없는지 여부를 알 수 있습니다. laravel 5.4에서 다음 코드는 내 문제를 해결했습니다.

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

여기서 두 번째 매개 변수 false 는 자동 증가 하지 않아야 함을 나타내고 세 번째 매개 변수 true 는 서명되지 않아야 함을 나타냅니다. 외래 키 제약 조건을 동일한 마이그레이션으로 유지하거나 분리 할 수 ​​있습니다. 둘 다 작동합니다.


1

위의 솔루션 중 초보자가 작동하지 않는 경우 두 ID가 모두 같은 유형인지 확인하십시오. 둘 다 integer또는 둘 다 bigInteger... ... 다음과 같이 할 수 있습니다.

메인 테이블 (예 : 사용자)

$table->bigIncrements('id');

어린이 테이블 (예 : 우선 순위)

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

때문에이 쿼리는 실패 할 것이다 users.idA는 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

또한 생성 마이그레이션 순서 일 수도 있습니다. 우선 순위 테이블을 먼저 작성하고 사후 사용자 테이블을 작성하면 테이블이 잘못됩니다. 첫 번째 마이그레이션으로 인해 사용자 테이블을 찾았습니다. 따라서 마이그레이션 순서를 변경해야합니다.

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

때때로이 오류는 마이그레이션 순서로 인해 발생할 수 있습니다.

사용자와 주문처럼 두 테이블

주문 테이블에 foriegn 사용자 키가 있습니다 (주문 테이블이 먼저 마이그레이션되는 경우 마이그레이션하는 동안 외래 키와 일치하는 사용자가 없기 때문에 문제가 발생 함)

해결 방법 : 주문 업데이트 테이블을 업데이트 할 사용자 아래에 두십시오.

예 : 제 경우에는 교육 및 대학 테이블 교육 테이블

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

여기에 대한 답변에서 누락 된 것으로 생각되는 것이 하나 있는데, 내가 틀렸다면 수정하십시오. 그러나 외래 키는 피벗 테이블에서 색인화해야합니다. 적어도 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.