Laravel 迁移:“外键约束的格式不正确”)
Laravel migration: “Foreign key constraint is incorrectly formed")
当我尝试执行 php artisan migrate
或 php artisan migrate:refresh
时我的迁移失败并出现以下错误:
errno: 150 "Foreign key constraint is incorrectly formed"
代码
用户Table(迁移成功)
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');
});
}
地址 Table(失败并出现错误)
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');
});
}
每个 table 上的数据类型必须与键控列完全匹配。在 users
上,id 是有符号整数,在 address
上,user 是无符号整数。我建议使用无符号整数作为 id,因为它永远不会变为负数,并为您提供更高的上限。
在你address
迁移而不是:
$table->integer('user')->unsigned();
放:
$table->integer('user');
FK 和参考密钥应该是同一类型。
您可以将 table 用户的 ID 更改为:
$table->id();
并将地址 table user
更改为 user_id
并尝试像这样更改外国 ID:
$table->foreignId('user_id')->constrained()->onDelete('cascade');
使用 Laravel 这样的框架的原因之一是语法糖。通过遵循他们的约定,您可以编写更少的代码,并且需要考虑更少的应用程序“具体细节”。
你做的恰恰相反,并且已经看到了后果。一旦您尝试建立模型及其关系,您将经历更多的痛苦。相反,您应该使用如下所示的迁移:
<?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
table;您希望以类似方式更新其迁移。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
// DO NOT use an enum column; create another table called roles instead
$table->foreignId('role_id')->constrained();
$table->string('name', 100);
$table->string('surname', 100);
$table->string('email', 100)->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->timestamps();
});
}
失败的原因如@aynber 所述。密钥的数据类型必须匹配。
遵循 Laravel 命名主键和外键的最佳实践也很重要。主键应为 'id',外键应为 table 名称(单数)下划线 id。例如,如果 table 名称是用户,那么 table 用户的外键应该是 'user_id'.
这里是 table 个地址(复数)
的示例
Schema::create('addresses', function (Blueprint $table) {
$table->id();
...
$table->foreignId('user_id')->constrained();
});
您不必提供 table 名称或另一个 table 的主键,因为 Laravel 会从外键中计算出来(user_id 翻译table 具有主键 ID 的用户)。稍后,当您创建 eloquent 模型时,您可以从模型中留下一些信息。
class Address {
public function user()
{
return $this->belongsTo(User::class);
}
}
在这里你不必指定$table
属性 也不必在belongsTo
方法中提供外键或主键。
当我尝试执行 php artisan migrate
或 php artisan migrate:refresh
时我的迁移失败并出现以下错误:
errno: 150 "Foreign key constraint is incorrectly formed"
代码
用户Table(迁移成功)
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');
});
}
地址 Table(失败并出现错误)
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');
});
}
每个 table 上的数据类型必须与键控列完全匹配。在 users
上,id 是有符号整数,在 address
上,user 是无符号整数。我建议使用无符号整数作为 id,因为它永远不会变为负数,并为您提供更高的上限。
在你address
迁移而不是:
$table->integer('user')->unsigned();
放:
$table->integer('user');
FK 和参考密钥应该是同一类型。
您可以将 table 用户的 ID 更改为:
$table->id();
并将地址 table user
更改为 user_id
并尝试像这样更改外国 ID:
$table->foreignId('user_id')->constrained()->onDelete('cascade');
使用 Laravel 这样的框架的原因之一是语法糖。通过遵循他们的约定,您可以编写更少的代码,并且需要考虑更少的应用程序“具体细节”。
你做的恰恰相反,并且已经看到了后果。一旦您尝试建立模型及其关系,您将经历更多的痛苦。相反,您应该使用如下所示的迁移:
<?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
table;您希望以类似方式更新其迁移。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
// DO NOT use an enum column; create another table called roles instead
$table->foreignId('role_id')->constrained();
$table->string('name', 100);
$table->string('surname', 100);
$table->string('email', 100)->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->timestamps();
});
}
失败的原因如@aynber 所述。密钥的数据类型必须匹配。
遵循 Laravel 命名主键和外键的最佳实践也很重要。主键应为 'id',外键应为 table 名称(单数)下划线 id。例如,如果 table 名称是用户,那么 table 用户的外键应该是 'user_id'.
这里是 table 个地址(复数)
的示例 Schema::create('addresses', function (Blueprint $table) {
$table->id();
...
$table->foreignId('user_id')->constrained();
});
您不必提供 table 名称或另一个 table 的主键,因为 Laravel 会从外键中计算出来(user_id 翻译table 具有主键 ID 的用户)。稍后,当您创建 eloquent 模型时,您可以从模型中留下一些信息。
class Address {
public function user()
{
return $this->belongsTo(User::class);
}
}
在这里你不必指定$table
属性 也不必在belongsTo
方法中提供外键或主键。