laravel errno 150外键约束不正确

Yrt*_*ymd 11 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();
        });
Run Code Online (Sandbox Code Playgroud)

运行迁移后出错:

[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")
Run Code Online (Sandbox Code Playgroud)

Sha*_*dow 23

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

您创建id在这两个领域users,并firms签署整数.但是,您将两个外键都创建为无符号整数,因此密钥的创建失败.

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

  • 忘记所有其他说这很重要的事情`被引用和引用字段必须具有完全相同的数据类型。`我几乎要上吊了。谢了哥们。 (5认同)
  • 太好了,对我有帮助。 (3认同)

Bob*_*Axe 11

这个答案并不比之前的六个答案更好,但是它是有关什么原因laravel-errno-150-foreign-key-constraint-is-incorrectly-formed以及如何专门为幼虫修复的更全面的答案。

1)拼写:有时,所引用column name或所引用的拼写错误table name可能会引发此错误,并且您不会知道,因为错误跟踪的描述性不是很高。

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

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');
 }
}
Run Code Online (Sandbox Code Playgroud)

要了解更多信息,请参阅laravel外键laravel迁移

提及我在评论中错过的更多修复程序。


May*_*iya 7

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

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

例如:

用户

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

订单

 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');
        });
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我试图从订单表中为用户表分配外键,但我在订单表中有bigInteger 数据表,而在用户表中,我有简单的整数。这就是它产生这种错误的原因。

此外,如果您使用了unsigned()nullable()等带有主键或外键的选项,那么您应该在这两个位置使用相同的选项。