一般错误:1215 无法添加外键约束,Laravel 5 & MySQL

Posted

技术标签:

【中文标题】一般错误:1215 无法添加外键约束,Laravel 5 & MySQL【英文标题】:General error: 1215 Cannot add foreign key constraint, Laravel 5 & MySQL 【发布时间】:2019-09-08 17:43:27 【问题描述】:

在一个空白的 Laravel 项目中,我想在 usersquestions 之间创建外键约束,其中 users 表将包含内置 Laravel User,但Question 将是自定义模型。

运行php artisan migrate后出现以下错误:

   Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `questions` add constraint `questions_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)
  at /home/artur/Exposit/EDU/PHP/lara/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) 
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         
    668| 

这里是 laravel 生成的 create_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();
        );

这是我的迁移:

Schema::create('questions', function (Blueprint $table) 
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->unsignedInteger('views')->default(0);
            $table->unsignedInteger('answers')->default(0);
            $table->integer('votes')->default(0);
            $table->unsignedInteger('best_answer_id')->nullable();
            $table->unsignedInteger('user_id');
            $table->timestamps();
        );

        Schema::table('questions', function (Blueprint $table) 
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        );

我尝试将问题表创建和使用外键约束更改为两个迁移,但得到了相同的错误。 请注意,*** 上的非相关答案对我有帮助。

【问题讨论】:

【参考方案1】:

Laravel 5.8 添加了 bigIncrements 作为默认值

所以外键字段类型不匹配。您在 User 表中看到 bigIncrements(id),在 questions 表中看到 unsigned Integer(user_id)。

如何解决

要么将原始迁移从 bigIncrements() 更改为 just 增量() 或者在你的外键列中做 unsignedBigInteger() 而不是 无符号整数()。

【讨论】:

通过使用 unsignedBigInteger 类型解决了我的问题。非常感谢!【参考方案2】:

在用户表bigIncrements('id') 中创建未签名的主键。

它的类型是大整数

当您设置外键时,它也应该是无符号的。

添加unsigned()函数并将类型从unsignedInteger更改为bigInteger

例子:

 Schema::create('questions', function (Blueprint $table) 
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->unsignedInteger('views')->default(0);
            $table->unsignedInteger('answers')->default(0);
            $table->integer('votes')->default(0);
            $table->unsignedInteger('best_answer_id')->nullable();
            $table->bigInteger('user_id')->unsigned();
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        );

【讨论】:

解决了我的问题。非常感谢:)【参考方案3】:

主键和外键的数据类型必须相同。

请将questions迁移更新为:

Schema::create('questions', function (Blueprint $table) 
    $table->bigIncrements('id');
    $table->string('title');
    $table->string('slug')->unique();
    $table->text('body');
    $table->unsignedInteger('views')->default(0);
    $table->unsignedInteger('answers')->default(0);
    $table->integer('votes')->default(0);
    $table->unsignedInteger('best_answer_id')->nullable();
    $table->bigInteger('user_id')->unsigned()->nullable();
    $table->timestamps();
);

Schema::table('questions', function (Blueprint $table) 
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
);

如果best_answer_id 也将成为外键,则也对它执行相同操作。

【讨论】:

【参考方案4】:

迁移源表的变化

Schema::create('table_name', function (Blueprint $table) 
$table->BigIncrements('id');

Schema::create('table_name', function (Blueprint $table) 
$table->increments('id');

【讨论】:

【参考方案5】:

我如何为 Laravel 8 修复它: L8 中生成的所有迁移仅使用$table->id();,即 bigInteger。确保在要包含外键的第二张表上,您有 $table->unsignedBigInteger('post_id');

先设置正确的类型:

posts table

Schema::create('posts', function (Blueprint $table) 
 $table->id(); //note by default in laravel 8 this is bigint
 $table->string('title')->nullable();
 $table->timestamps();
);

comments table

Schema::create('comments', function (Blueprint $table) 
 $table->id();
 $table->string('description')->nullable();
 //foriegn key set up below
 $table->unsignedBigInteger('post_id');
 $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');

);

第二次重新排序迁移文件(在运行 cmets 文件之前应该先运行帖子迁移,因为 laravel 找不到帖子的 id 来创建外键)

2021_04_10_043454_create_posts_table -> 04/10(较早的日期将首先运行) 2021_04_14_050712_create_posts_table -> 04/14(之后的日期)

最后, 先清除缓存php artisan cache:clear 然后运行php artisan migrate

【讨论】:

以上是关于一般错误:1215 无法添加外键约束,Laravel 5 & MySQL的主要内容,如果未能解决你的问题,请参考以下文章

一般错误:1215 无法添加外键约束,Laravel 5 & MySQL

SQLSTATE[HY000]:一般错误:1215 无法添加外键约束 Laravel 5.8

SQLSTATE[HY000]:一般错误:1215 无法添加外键约束 [Laravel 7.0]

SQLSTATE[HY000]:一般错误:1215 无法在表用户中添加外键约束 Laravel

Laravel 5.0 [PDOException] SQLSTATE[HY000]:一般错误:1215 无法添加外键约束

Laravel - 1215 无法添加外部约束