laravel errno 150外键约束不正确

问题描述 投票:11回答:8

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

有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")
php mysql laravel-5.3
8个回答
21
投票

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

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

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


4
投票

大多数情况下,由于表中的数据类型不匹配而发生此类错误。

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

例如:

用户

        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()etc选项,那么您应该在这两个地方使用相同的选项。


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)遗留物:当发生此错误时,并不表示该表未迁移而是迁移但未设置外键列且未添加到migration table因此运行php artisan migrate:reset将删除除故障表之外的其他表,因此建议手动删除故障表以避免进一步的错误。

5)顺序:这通常是这个错误的最常见原因,在referenced其他工匠不会找到集成外键的位置之前必须创建或迁移表reference table。确保迁移过程的顺序重命名迁移文件示例:

  • 表A:2014_10_12_000000_create_users_table.php
  • 表B:2014_10_12_100000_create_password_resets_table.php

这表明表A将始终在表B之前进行更改,我将表B重命名为2014_10_11_100000_create_password_resets_table.php,现在它将在表A之前迁移。

6)启用外键:如果所有其他方法都失败,则在迁移代码示例之前在Schema::enableForeignKeyConstraints();中添加function up()

class CreateUsersTable extends Migration
{
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
    Schema::enableForeignKeyConstraints();
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
 }

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

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

提及我在评论中错过的任何更多修复感谢。


1
投票
  • 用户
  • 收银员指的是用户
  • 学生指的是收银员

此外,在laravel中声明外键时,您所引用的所有表都必须位于顶部。在这种情况下,您可以使用“ - > unsigned()”修​​饰符..


1
投票

我们是桌子villes:

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

1
投票

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

$table->unsignedBigInteger('user_id');

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


0
投票

当您测试laravel应用程序并且在测试中使用了MySQL实例时,会发生这种情况,这些实例受数据库迁移的影响。

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.