laravel errno 150外键约束不正确

时间:2016-11-29 10:30:03

标签: php mysql laravel-5.3

有人可以帮我解决这个问题吗?

有3个表有2个外键:

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

        Schema::create('firms', function (Blueprint $table) {
                    $table->increments('id');
                    $table->string('title')->nullable();  
                    $table->integer('user_id')->unsigned()->nullable();
                    $table->foreign('user_id')->references('id')->on('users');
                    $table->timestamps();
                });
       Schema::create('jobs', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title')->nullable();
            $table->integer('firm_id')->unsigned()->nullable();
            $table->foreign('firm_id')->references('id')->on('firms');
            $table->timestamps();
        });

运行迁移后出错:

[Illuminate\Database\QueryException]
  SQLSTATE[HY000]: General error: 1005 Can't create table `job`.`#sql-5fc_a1`
   (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter ta
  ble `firms` add constraint `firms_user_id_foreign` foreign key (`user_id`)
  references `users` (`id`))

  [PDOException]
  SQLSTATE[HY000]: General error: 1005 Can't create table `job`.`#sql-5fc_a1`
   (errno: 150 "Foreign key constraint is incorrectly formed")

16 个答案:

答案 0 :(得分:20)

如果是外键,引用和引用字段必须具有完全相同的数据类型。

您可以将idusers中的firms字段创建为签名整数。但是,您将两个外键都创建为无符号整数,因此密钥的创建失败。

您需要将unsigned子句添加到id字段定义,或从外键字段中删除unsigned子句。

答案 1 :(得分:2)

大多数情况下,由于两个表上的数据类型不匹配,都会发生这种错误。

主键表和外键表都应使用相同的数据类型和相同的选项。

例如:

用户

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

订单

 Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('product_id')->unsigned();
            $table->foreign('product_id')->references('id')->on('products');
            $table->bigInteger('user_id')->unsigned();
           $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

            $table->timestamp('added_on');
        });

在上面的示例中,我试图将外键分配给订单表中的用户表,但订单表中有 bigInteger 数据表,而在用户表中,我有简单的整数。这就是为什么它会产生这种错误。

此外,如果您已将 unsigned() nullable()等选项与主键或外键一起使用,则应在两个地方都使用相同的选项。

答案 2 :(得分:2)

这个答案并不比之前的六个答案更好,但是它是关于laravel-errno-150-foreign-key-constraint-is-incorrectly-formed的起因以及如何专门针对laravel的更全面的答案。

1)拼写:通常有时对引用的column name或引用的table name的拼写错误会引发此错误,并且您不会将其称为错误跟踪不是很描述。

2)唯一:通过在迁移中的列定义中添加->primary()或添加->unique(),引用的列必须是唯一的。

3)数据类型:被引用字段和引用字段必须具有完全相同的数据类型。这还不够强调。

  • 对于bigincrements的预期数据类型为bigInteger('column_name')->unsigned();

  • 预计increments
  • integer('column_name')->unsigned();等。

4)残次:发生此错误并不表示表未迁移而是表被迁移,但未设置外键列且未将其添加到{{1 }},因此运行migration table会删除除故障表以外的其他表,因此建议手动删除故障表以避免进一步的错误。

5)订单:这通常是导致此错误的最常见原因,必须先创建或迁移正在php artisan migrate:reset的表,然后其他技术人员才能找到要放置的位置。集成外键。确保迁移过程的顺序重命名迁移文件示例:

  • 表A:referenced
  • 表B:reference table

这表明表A总是会在表B之前出现,以进行更改,我将表B重命名为2014_10_12_000000_create_users_table.php,现在它将在表A之前迁移。

6)启用外键:如果所有其他操作均失败,则在迁移代码示例之前的2014_10_12_100000_create_password_resets_table.php内添加2014_10_11_100000_create_password_resets_table.php

Schema::enableForeignKeyConstraints();

要了解更多信息,请参见laravel foreign keylaravel migrations

提及我在评论中错过的其他修复程序。

答案 3 :(得分:2)

public function up() {     Schema::create('companies', function (Blueprint $table) {         $table->bigIncrements('id');         $table->string('name');         $table->text('address');         $table->string('tel1');         $table->string('tel2');         $table->integer('owner');         $table->unsignedBigInteger('access_id');         $table->string('depot_number')->default(2);         $table->timestamps();           $table->foreign('access_id')->references('id')->on('accesses')             ->onDelete('cascade');     }); } 

public function up() {     Schema::create('accesses', function (Blueprint $table) {         $table->bigIncrements('id');         $table->string('type');         $table->string('description');         $table->timestamps();     }); } 

在您的数据库/迁移文件夹中,按名称排序。然后确保 create_accesses_table 在此处 create_companies_table 之前:

here

答案 4 :(得分:1)

  • 用户
  • 收银员指用户
  • 学生提出收银员

此外,当在laravel中声明外键时,您所引用的所有表必须位于顶部。在这种情况下,您可以使用" - > unsigned()"改性剂..

答案 5 :(得分:1)

我们是桌游:

Schema::create('villes', function (Blueprint $table) {
            $table->bigIncrements('idVille'); // bigIncrement(8 bits)
            $table->string('nomVille');
            $table->timestamps();
        });
表用户中的

外键:

Schema::table('users', function (Blueprint $table) {
            $table->bigInteger('ville_idVille')->unsigned()->after('tele');
            $table->foreign('ville_idVille')->references('idVille')->on('villes');
        });

答案 6 :(得分:1)

对于PHP laravel 5.8,使用此格式的unsigned修饰符

$table->unsignedBigInteger('user_id');

删除数据库中的所有表,然后再次运行迁移

答案 7 :(得分:0)

当您测试laravel应用程序并且在测试中使用了MySQL实例(取决于数据库迁移)时,就会发生这种情况。

在运行测试之前,我的迁移工作正常。然后我遇到了这个错误。

我解决此问题的方法是简单地删除整个数据库并重新创建它。然后再次迁移。

答案 8 :(得分:0)

如果您设置引用字段并且具有完全相同的数据类型,但是存在错误 您可以更改日期迁移文件  只是它的工作

答案 9 :(得分:0)

如果引用表的主键位于BigIcrements中,则将BigInteger用于外键也如下所示

表ATable

public function up()
{
    Schema::create('a_tables', function (Blueprint $table) {
        $table->bigIncrements('id');
   }
}

TABLE BTable

public function up()
{
    Schema::create('b_tales', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('a_tables_id')->unsigned();
     $table->foreign('a_tables_id')->references('id')->on('a_tables')->onDelete('cascade');
   }
}

答案 10 :(得分:0)

我尝试了此线程中提供的所有答案。

什么都没有。

然后我发现我忘记了删除phpMyadmin中的“迁移”表。

我从phpMyAdmin中删除了所有表,但删除了migrations表。这就是为什么错误反复存在的原因。

答案 11 :(得分:0)

这个答案与Laravel 7.x有关。所以错误:

errno:150“外键约束的格式不正确”

在迁移迁移过程中,由于许多原因可能会发生

。我熟悉的一个常见原因是迁移顺序。

让我们说我们有两个表“ users”和“ roles”,“ users”表有一个外键,引用了“ roles”表上的“ id”列。因此,请确保将“角色”迁移到“用户”表之前。

因此,迁移顺序很重要。这很明显,因为MySQL引用未知表的“ id”列是没有意义的。

第二个原因是错误的数据类型。在laravel 7.x中,我们对主键使用“ id()”方法。因此,请确保预期的外键(在我的情况下为“ users”表中的“ role_id”)为“ bigInteger”且为“ unsigned”。

这是我的代码:

Schema::create('roles', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('slug')->nullable();
        $table->timestamps();
    });


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

        $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
    });

public function down()
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->dropForeign('users_role_id_foreign'); 
    });
    Schema::dropIfExists('users');
}

因此在上面的代码中,我必须先迁移“角色”表,然后再迁移“用户”表。因此,MySQL可以为角色表创建外键。

该怎么办,我将子迁移(具有外键的迁移)移动到临时文件夹。并在迁移父迁移(在我的情况下为“ roles”表,然后迁移子迁移(“ users”迁移)之后)将其还原。

还有一个提示:在删除依赖迁移(包含外键的迁移)时,首先要删除外键。而且Laravel在删除外键“ _ _foreign”时使用特定的命名约定。

编码愉快,可以为PHP 8的突破性发布做好准备。

答案 12 :(得分:0)

这里的主要概念是你必须确保主键和外键的类型相同。例如,让你的第一个表迁移是

public function up()
{
    Schema::create('chapters', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->timestamps();
    });
}

那么你的第二个表迁移将是

public function up()
{
    Schema::create('classifications', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->unsignedBigInteger('chapter_id');
        $table->timestamps();
        $table->foreign('chapter_id')->references('id')->on('chapters')->onDelete('cascade');
    });
}

这里“chapter”表中的“id”和“classifications”表中的“chapter_id”相同,即“unsignedBigInteger”。

再次,如果你得到错误,然后将“章节”表中的“ $table->id(); ”更改为“ $table->bigIncrements('id'); ”。

希望对你有帮助

答案 13 :(得分:0)

对于 laravel 7 迁移错误

("SQLSTATE[HY000]: General error: 1005 Can't create table laraveltesting.reviews (errno: 150 "外键约束的格式不正确")")

迁移顺序是最重要的,所以应该先迁移父表然后才迁移子表 图 1:migration order while getting error


        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('detail');
            $table->float('price');
            $table->integer('stock');
            $table->float('discount');
            $table->timestamps();
        });
 Schema::create('reviews', function (Blueprint $table) {
            $table->id();
            $table->foreignId('product_id')->constrained('products')->cascadeOnDelete();
            $table->string('customer');
            $table->text('review');
            $table->integer('star');

            $table->timestamps();
        });

这会导致迁移时出现错误,可以通过更改迁移顺序来解决此问题,方法是将迁移重命名为图 1 中的图 2 所示。应首先迁移书籍表,然后仅迁移评论表

图片 2:Order of migration for the successful migration

答案 14 :(得分:0)

如果你得到错误改变 $table->id()(references) by $table->increments('id')

答案 15 :(得分:0)

尽一切努力和我一起工作

从数据库和(迁移表)中删除(用户表)
然后“取消注释”您的外键关系
示例: $table->string('pass1'); $table->foreign('pass1')->references('email')->on('abs');
然后运行:php artisan migrate 顺利运行 enter image description here

enter image description here