Laravel 迁移:“外键约束形成不正确”)

时间:2020-12-29 16:24:49

标签: php mysql laravel laravel-migrations

当我尝试执行 php artisan migratephp artisan migrate:refresh 时出现此错误,我的迁移失败:

errno: 150 "Foreign key constraint is incorrectly formed"

代码

用户表(迁移成功)

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->integer('id',)->primary();
        $table->string('name', 255);
        $table->string('surname', 255);
        $table->string('email', 255)->unique();
        $table->string('password', 255);
        $table->string('profile_image', 255);
        $table->string('profile_cover', 255);
        $table->rememberToken();
        $table->char('token', 255)->unique()->nullable()->default(null);
        $table->enum('role', ['user', 'driver', ',merchant', 'storemanager', 'storeoperator', 'company', 'employee']);
        $table->dateTime('created');
        $table->dateTime('updated');
    });
}

地址表(因错误而失败)

public function up()
{
    Schema::create('address', function (Blueprint $table) {
        $table->integer('id')->primary();
        $table->string('address1');
        $table->string('address2');
        $table->string('city');
        $table->integer('country')->unsigned();
        $table->decimal('latitude');
        $table->decimal('longitude');
        $table->string('instructions');
        $table->integer('default');
        $table->integer('user')->unsigned();
        $table->dateTime('created');
        $table->dateTime('updated');
        $table->foreign('country')->references('id')->on('country')->onUpdate('cascade');
        $table->foreign('user')->references('id')->on('users')->onUpdate('cascade');

    });
}

5 个答案:

答案 0 :(得分:2)

使用 Laravel 等框架的原因之一是语法糖。通过遵循他们的约定,您可以编写更少的代码,并且不必考虑应用程序的“具体细节”。

您的做法与此相反,并且已经看到了后果。一旦您尝试建立模型及其关系,您将经历更多的痛苦。相反,您应该使用如下所示的迁移:

Script path

还有<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateAddressesTable extends Migration { public function up() { // table names are plural of the object name Schema::create('addresses', function (Blueprint $table) { // automatically create an incrementing bigint column called 'id' $table->id(); // name foreign ID columns correctly to save yourself trouble later $table->foreignId('country_id')->constrained(); $table->foreignId('user_id')->constrained(); // specify lengths for your varchar columns $table->string('address1', 100); $table->string('address2', 100); $table->string('city', 100); $table->decimal('latitude'); $table->decimal('longitude'); $table->string('instructions', 100); $table->integer('default'); // why would you define your own timestamp columns with non-standard names? $table->timestamps(); }); } } 表;您希望类似地更新其迁移。

users

答案 1 :(得分:0)

每个表上的数据类型必须与键控列完全匹配。在 users 上,id 是一个有符号整数,在 address 上,user 是一个无符号整数。我建议为 id 使用无符号整数,因为它永远不会变为负数,并为您提供更高的上限。

答案 2 :(得分:0)

在你--env迁移而不是:

address

放置:

$table->integer('user')->unsigned();

FK 和引用键的类型应该相同。

答案 3 :(得分:0)

您可以将表用户的 id 更改为:

$table->id();

并将地址表 user 更改为 user_id 并尝试像这样更改外部 ID:

$table->foreignId('user_id')->constrained()->onDelete('cascade');

答案 4 :(得分:0)

失败的原因是@aynber 提到的。键的数据类型必须匹配。

遵循 Laravel 命名主键和外键的最佳实践也很重要。主键应该是“id”,外键应该是表名(单数)下划线 id。例如,如果表名是 users,那么表 users 的外键应该是 'user_id'。

这里是表地址的例子(复数)

    Schema::create('addresses', function (Blueprint $table) {
        $table->id();
        ...

        $table->foreignId('user_id')->constrained();
    });

您不必提供表名或另一个表的主键,因为 Laravel 会从外键(user_id 转换为具有主键 id 的表用户)计算出来。稍后,当您创建雄辩的模型时,您可以从模型中留下一些信息。

    class Address {

        public function user()
        {
            return $this->belongsTo(User::class);
        }
    }

此处不必指定 $table 属性,也不必在 belongsTo 方法中提供外键或主键。