我试图在Laravel中创建外键,但是当我使用artisan迁移我的表时,我抛出了以下错误:

[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign 
key (`user_id`) references `users` (`id`))     

我的迁移代码如下:

优先级迁移文件

public function up()
{
    //
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id');
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
}

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

用户迁移文件

public function up()
{
    //
    Schema::table('users', function($table)
    {
    $table->create();
    $table->increments('id');
    $table->string('email');
    $table->string('first_name');
    $table->string('password');
    $table->string('email_code');
    $table->string('time_created');
    $table->string('ip');
    $table->string('confirmed');
    $table->string('user_role');
    $table->string('salt');
    $table->string('last_login');

    $table->timestamps();
    });
}

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

关于我做错了什么,我现在想要得到这个,因为我有很多表,我需要创建例如用户,客户端,项目,任务,状态,优先级,类型,团队。理想情况下,我想创建表持有这些数据与外键,即clients_project和project_tasks等。

希望有人能帮我开始。


当前回答

我在laravel 5.8有这个问题,我修复了这个代码,如laravel文档中所示,在我添加外键的地方。

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

然后我运行$ PHP artisan migrate:refresh

由于这种语法相当冗长,Laravel提供了额外的、更简洁的方法,使用约定来提供更好的开发体验。上面的例子可以这样写:

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
});

其他回答

拉拉维尔 ^5.8

从Laravel 5.8开始,迁移存根在ID上使用bigIncrements方法 列。方法创建ID列 增量的方法。 这不会影响项目中的任何现有代码;然而,是 注意外键列必须具有相同的类型。因此,一个 使用increments方法创建的列不能引用列 使用bigIncrements方法创建。 来源:Migrations & bigIncrements


例子

假设您正在构建一个简单的基于角色的应用程序,并且需要在PIVOT表“role_user”中引用user_id。

2019年_05_05_112458_create_users_table.php

// ... public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('full_name'); $table->string('email'); $table->timestamps(); }); } 2019_05_05_120634_create_role_user_pivot_table.php // ... public function up() { Schema::create('role_user', function (Blueprint $table) { // this line throw QueryException "SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint..." // $table->integer('user_id')->unsigned()->index(); $table->bigInteger('user_id')->unsigned()->index(); // this is working $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); } As you can see, the commented line will throw a query exception, because, as mentioned in the upgrade notes, foreign key columns must be of the same type, therefore you need to either change the foreing key (in this example it's user_id) to bigInteger in role_user table or change bigIncrements method to increments method in users table and use the commented line in the pivot table, it's up to you. I hope i was able to clarify this issue to you.

2021年4月20日

在Laravel 8中,我遇到了这个问题。如果不使用nullable(),则可能发生此错误。

$table->bigInteger('user_id')->nullable()->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('set null');

为了在laravel中添加外键约束,我使用了以下方法:

创建列为外键,如下所示: 表- >美元整数(column_name) - >无符号(); 在(1)之后立即添加约束行,即。 表- >美元整数(column_name) - >无符号(); 表- >外国(column_name) - >引用(pk_of_other_table) - >(“other_table”);

使用Laravel 5.3也有同样的问题。

解决方案是使用unsignedInteger而不是integer('name')->unsigned()。

这就是有效的方法

$table->unsignedInt('column_name');
$table->foreign('column_name')->references('id')->on('table_name');

这样做的原因是,当使用integer('name')->unsigned时,在表中创建的列的长度为11,但当使用unsigedInteger('name')时,列的长度为10。

长度10是使用Laravel时主键的长度,因此列的长度匹配。

另一个原因可能是DB引擎类型。Laravel默认使用MyISAM引擎。所以如果你需要强制外键引用检查,你应该使用InnoDB作为你的引擎。

这个设置在config/database.php文件中。将引擎改为'engine' => 'InnoDB'

另外,如果您试图对现有表执行此操作,请使用

DB::statement("ALTER TABLE ' {$tableName} ' ENGINE = 'InnoDB'");