Laravel MySQL 数据库迁移 "Cannot add foreign key constraint" 错误

Laravel migration "Cannot add foreign key constraint" error with MySQL database

我正在开发 Laravel 应用程序。我正在为数据库使用 MySQL。我已经创建了一个模型 class 并正在尝试 运行 对其进行迁移。但是,当我 运行 迁移时,我在添加外键约束时遇到错误。这是我到目前为止所做的。

首先,我迁移了内置的 Laravel 用户模型 运行 使用此命令。

php artisan migrate

已在数据库中创建用户 table。

然后我用这个命令创建了另一个模型运行。

php artisan make:model TodoItem -m

然后我在迁移文件中添加了以下代码

class CreateTodoItemsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todo_items', function (Blueprint $table) {
            $table->text('about');
            $table->integer('user_id');
            $table->increments('id');
            $table->timestamps();

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

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

正如您在上面看到的,我通过向 todo_items [=41= 添加外键来建立用户 table 和 todo_items table 之间的关系].然后,我尝试通过 运行ning 这个命令来迁移 TodoItem 模型。

php artisan migrate

当我 运行 命令时,我得到了这个错误。

  Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `todo_items` add constraint `todo_items_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade)

  at /var/www/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| 

 Exception trace:

  1   PDOException::("SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint")
      /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  2   PDOStatement::execute()
      /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  Please use the argument -v to see more details.

我在我以前使用 Postgresql 的项目中做了同样的事情。我工作得很好。对于这个项目,我正在使用 MySQL 数据库,现在它给我上面的错误。

这是因为您在迁移文件中添加了 $table->integer('user_id');。您必须添加 unsignedInteger 而不是 integer,因为 users table 的原始 id 列是 unsigned(并且两列都必须完全一样)。

[编辑]

自 Laravel 5.8 起,默认 users table 的 id 列类型不再是 integer。现在是 bigInteger.

改变这个

$table->integer('user_id');

对此

$table->unsignedInteger('user_id')->nullable(false);

像这样尝试运行,应该可以。

// 还有,做我上面的人发布的未签名的东西

public function up()
{
    Schema::create('todo_items', function (Blueprint $table) {
        $table->text('about');
        $table->integer('user_id');
        $table->increments('id');
        $table->timestamps();

    });
    Schema::table('todo_items', function(Blueprint $table) {
        $table->foreign('user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE');
    });
}

问题是 mysql 在 table 创建期间不需要外键,或者 laravel 以错误的顺序发出外键。

简而言之,这没有用:

Schema::create('todo_items', function (Blueprint $table) {
    $table->text('about');
    $table->integer('user_id')->unsigned();
    $table->increments('id');
    $table->timestamps();

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

这有效:

  Schema::create('todo_items', function (Blueprint $table) {
    $table->text('about');
    $table->integer('user_id')->unsigned();
    $table->increments('id');
    $table->timestamps();

});

Schema::table('todo_items',  function(Blueprint $table){

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

尝试

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