【问题标题】:Errno: 150 "Laravel Migration Foreign key constraint is incorrectly formed"Errno:150“Laravel 迁移外键约束的格式不正确”
【发布时间】:2018-10-08 17:11:39
【问题描述】:

用户代码

    public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->integer('role_id')->unsigned();
        $table->foreign('role_id')->references('id')->on('user_role')->onDelete('cascade');
        $table->rememberToken();
        $table->timestamps();
    });
}

用户角色代码

    public function up()
{
    Schema::create('user_roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('user_role');
        $table->timestamps();
    });
}

SQLSTATE[HY000]: 一般错误: 1005 Can't create table sms.#sql-1718_62 (errno: 150 "外键约束格式不正确") (SQL: alter table users add constraint users_role_id_foreign外键(role_id)在删除级联时引用user_roleid

【问题讨论】:

  • 甚至添加 $table->integer('role_id')->unsigned();也有错误。我可以知道是什么问题吗?

标签: php laravel


【解决方案1】:

如果你想引用一个外键,请不要用

创建它
$table->integer('role_id')->unsigned(); 

你应该使用

$table->unsignedInteger('role_id');

这与迁移部分中的文档有关:Laravel Migrations

所以你的新语句最终应该看起来像

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->unsignedInteger('role_id');
        $table->foreign('role_id')->references('id')->on('user_role')->onDelete('cascade');
        $table->rememberToken();
        $table->timestamps();
    });
}

编辑:

作者添加user_role表的迁移代码后问题就清楚了。

作者所引用的表名为user_roles,与外键迁移user_role中没有提到。

所以这里是应该适用于 users 表的迁移。

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->unsignedInteger('role_id');
        $table->foreign('role_id')->references('id')->on('user_roles')->onDelete('cascade'); // change this line
        $table->rememberToken();
        $table->timestamps();
   });
 }

命名与 Laravel 命名约定有关,其中所有表都以复数命名,而所有模型都以单数命名。

编辑 2:

OP 提到他的迁移顺序错误,迁移无效的原因是什么。

users 表在 user_roles 表之前创建。这就是外键导致错误的原因。

希望对您有所帮助!如果您还有任何问题,请告诉我!

【讨论】:

  • 嗯,我在 OP 代码中的任何地方都没有看到 $table->string('role_id')->unsigned();
  • $table->unsignedInteger('role_id'); 相当于 $table->integer('role_id')->unsigned(); 虽然
  • 是的...我尝试了两种方式也得到了同样的错误,除了我删除了外键。这个问题与模型有关吗?
  • 引用 API 时它们并不等价。使用的 unsigned() 函数将给定类型转换为无符号。 unsignedInteger() 函数将整数转换为 4 字节长整数。主键甚至存储为 4 字节 int。因此,使用 unsignedInt 您可能会在那里提供长度问题。
  • @user10354117 可能是,role_id 的类型不是整数?您可以在数据库中检查一下,并发布相关 user_role 表的 sql 结构吗?
【解决方案2】:

这个问题很模糊。如果引用列和外键列的类型不同,也可能发生这种情况。

例如:如果外键列是 SMALLINT(5) UNSIGNED 并且引用的列是 INT(10) UNSIGNED。

【讨论】:

  • 已检查。他们都使用 int(10)。所以我认为不是这个问题。
【解决方案3】:

在此处输入您的代码:

       $table->foreign('role_id')->references('id')->on('user_role')->onDelete('cascade');

你正在裁判 user_role 表,但你没有这个表,你有 user_roles 表所以将 user_role 设置为 user_roles

       $table->foreign('role_id')->references('id')->on('user_roles')->onDelete('cascade');

希望这能解决你的问题

【讨论】:

    【解决方案4】:

    您传递的表名不正确。它应该是 user_roles 而不是 user_role 因为您创建了名为 user_roles 的表

    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->integer('role_id')->unsigned();
        $table->foreign('role_id')->references('id')->on('user_roles')->onDelete('cascade');
        $table->rememberToken();
        $table->timestamps();
    });
    

    【讨论】:

      猜你喜欢
      • 2018-05-23
      • 2015-12-16
      • 2019-09-10
      • 2017-04-13
      • 2019-09-17
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多