Laravel Migration外键约束不正确

Muh*_*req 26 mariadb laravel-5 laravel-6

迁移我的数据库时出现此错误,下面是我的代码,后面是我在尝试运行迁移时遇到的错误.

 public function up()
    {
        Schema::create('meals', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->integer('category_id')->unsigned();
            $table->string('title');
            $table->string('body');
            $table->string('meal_av');
            $table->timestamps();

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

            $table->foreign('category_id')
                ->references('id')
                ->on('categories')
                ->onDelete('cascade');
        });
    }  
Run Code Online (Sandbox Code Playgroud)

错误信息

[Illuminate\Database\QueryException]                                         
      SQLSTATE[HY000]: General error: 1005 Can't create table `meal`.`#sql-11d2_1  
      4` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter   
      table `meals` add constraint meals_category_id_foreign foreign key (`catego  
      ry_id`) references `categories` (`id`) on delete cascade) 
Run Code Online (Sandbox Code Playgroud)

小智 38

在Laravel中创建新表时。迁移将生成为:

$table->bigIncrements('id');
Run Code Online (Sandbox Code Playgroud)

而不是(在较旧的Laravel版本中):

$table->increments('id');
Run Code Online (Sandbox Code Playgroud)

使用bigIncrements外键时,需要一个bigInteger而不是一个integer。因此,您的代码将如下所示:

public function up()
    {
        Schema::create('meals', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedBigInteger('user_id'); //changed this line
            $table->unsignedBigInteger('category_id'); //changed this line
            $table->string('title');
            $table->string('body');
            $table->string('meal_av');
            $table->timestamps();

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

            $table->foreign('category_id')
                ->references('id')
                ->on('categories')
                ->onDelete('cascade');
        });
    }  
Run Code Online (Sandbox Code Playgroud)

你也可以使用increments,而不是bigIncrements马切达Sejio说。

Integer和BigInteger之间的区别是大小:

  • int => 32位
  • bigint => 64位

  • 对于所有最新的laravel版本(5.8),这都是一个很好的答案-谢谢Swooth。 (3认同)

Muh*_*req 17

@JuanBonnett你的问题激发了我的答案,我在laravel上采用了自动化过程而不考虑文件本身的创建时间.根据工作流程,将在表(类别)之前创建膳食,因为我已经创建了模式文件(膳食)在类别之前.那是我的错.

  • 这么愚蠢的事情:(,它应该像数据库播种器一样。我们必须定义订单。 (2认同)

小智 12

只需->unsigned()->index()在外键的末尾添加它就可以了

  • index()是多余的,因为默认情况下外键将在该列上生成索引 (2认同)
  • 对我来说只需添加 - > unsigned()就可以了. (2认同)

小智 10

对我来说,一切都是正确的顺序,但它仍然无法正常工作.然后我通过摆弄来发现主键必须是无符号的.

//this didn't work
$table->integer('id')->unique();
$table->primary('id');

//this worked
$table->integer('id')->unsigned()->unique();
$table->primary('id');

//this worked 
$table->increments('id');
Run Code Online (Sandbox Code Playgroud)


aph*_*hoe 8

如果你正在使用->onDelete('set null')你的外键定义确保外键字段本身nullable()

//Column definition
$table->integer('user_id')->unsigned()->index()->nullable(); //index() is optional

//...
//...

//Foreign key 
$table->foreign('user_id')
      ->references('id')
      ->on('users')
      ->onDelete('set null');
Run Code Online (Sandbox Code Playgroud)

  • 你是一个传奇! (2认同)

Hus*_*dil 8

Laravel 5.8

在外键列中使用unsignedBigInteger来避免外键数据类型不匹配的问题。例如,假设我们有两个表问题回复
问题表将如下所示:

 public function up()
    {
        Schema::create('questions', function (Blueprint $table) {
            $table->bigIncrements('id');
             $table->text('body');
             $table->integer('user_id')->unsigned();
            $table->timestamps();
        });
    }
Run Code Online (Sandbox Code Playgroud)

回复表如下所示:

public function up()
{
    Schema::create('replies', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->text('body');
        $table->unsignedBigInteger('question_id');
        $table->integer('user_id')->unsigned();
        $table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
        $table->timestamps();
    });
}
Run Code Online (Sandbox Code Playgroud)


Man*_*zar 6

迁移必须自上而下创建。

首先为不属于任何人的表创建迁移。

然后为属于前一个的表创建迁移。


表引擎问题的简化答案:

要为表设置存储引擎,请在架构构建器上设置引擎属性:

Schema::create('users', function ($table) {
    $table->engine = 'InnoDB';

    $table->increments('id');
});
Run Code Online (Sandbox Code Playgroud)

来自 Laravel 文档:https ://laravel.com/docs/5.2/migrations


小智 5

您应该创建迁移, 例如,我希望我users拥有一个role_id来自roles表的字段

首先开始进行角色迁移 php artisan make:migration create_roles_table --create=roles

然后是我的第二个用户迁移 php artisan make:migration create_users_table --create=users

php artisan migration将使用创建的文件 2017_08_22_074128 _create_roles_table.php和2017_08_22_134306 _create_users_table的顺序执行,检查日期时间顺序,即执行顺序。

文件2017_08_22_074128_create_roles_table.php

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name', 50);
        $table->timestamps();
    });
}
Run Code Online (Sandbox Code Playgroud)

2017_08_22_134306_create_users_table

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('role_id')->unsigned();
        $table->string('name');
        $table->string('phone', 20)->unique();
        $table->string('password');
        $table->rememberToken();
        $table->boolean('active');
        $table->timestamps();
        $table->foreign('role_id')->references('id')->on('roles');
    });
}
Run Code Online (Sandbox Code Playgroud)


Kik*_*ijo 5

以我为例,新的laravel约定导致了此错误。

仅通过表创建的简单交换就可以达到目的id

$table->increments('id'); // ok
Run Code Online (Sandbox Code Playgroud)

, 代替:

$table->bigIncrements('id'); // was the error.
Run Code Online (Sandbox Code Playgroud)

已经使用Laravel v5.8,以前从未发生此错误。

  • 这个答案是正确的。它适用于Laravel 5.8。 (2认同)

Bas*_*har 5

对于数据类型未匹配问题,我得到了相同的消息。

我将bigIncrements()用作'id',当我将其用作外键(使用bigInteger())时,出现了错误。

我找到了解决方案,bigIncrements()返回unsignedBigInteger。因此需要在外键中使用unsignedBigInteger()而不是bigInteger()

分享此内容,因为它可能会帮助其他人


muj*_*nly 5

Laravel 6:2020 年 1 月 17 日更新

$table->bigInteger( 'category_id' )->unsigned();
Run Code Online (Sandbox Code Playgroud)

这对我很有效


Saf*_*yas 5

我不得不在 Laravel 6 中面临同样的问题。我通过以下方式解决了这个问题。

我认为它可以帮助您或其他人:

    $table->bigIncrements('id');
    $table->bigInteger('user_id')->unsigned(); //chnage this line
    $table->bigInteger('category_id')->unsigned(); //change this line
    ---
    $table->foreign('user_id')
        ->references('id')
        ->on('users')
        ->onDelete('cascade');
    $table->foreign('category_id')
        ->references('id')
        ->on('categories')
        ->onDelete('cascade');
Run Code Online (Sandbox Code Playgroud)

使用等效的“大整数”递增 ID。

使用 bigInteger 而不是 Integer

  1. 如果现在仍然出现错误。

我建议您通过以下方式重新排序迁移文件:

更改构成迁移文件名第一部分的日期,使它们按您想要的顺序排列(例如:对于 2020_07_28_133303_update_categories.php,日期和时间为 2020-07-28, 13:33:03);

注意:首先必须是“类别”迁移文件而不是“膳食”迁移文件。

注意:在 Laravel 5.6 中,对于$table->increments('id'); 用$table->integer('user_id')->unsigned();