laravel errno 150 外键约束格式不正确
Posted
技术标签:
【中文标题】laravel errno 150 外键约束格式不正确【英文标题】:laravel errno 150 foreign key constraint is incorrectly formed 【发布时间】:2017-04-13 07:25:45 【问题描述】:谁能帮我解决这个问题?
有 3 个表有 2 个外键:
Schema::create('users', function (Blueprint $table)
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
);
Schema::create('firms', function (Blueprint $table)
$table->increments('id');
$table->string('title')->nullable();
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
);
Schema::create('jobs', function (Blueprint $table)
$table->increments('id');
$table->string('title')->nullable();
$table->integer('firm_id')->unsigned()->nullable();
$table->foreign('firm_id')->references('id')->on('firms');
$table->timestamps();
);
运行迁移后出错:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1005 Can't create table `job`.`#sql-5fc_a1`
(errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter ta
ble `firms` add constraint `firms_user_id_foreign` foreign key (`user_id`)
references `users` (`id`))
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table `job`.`#sql-5fc_a1`
(errno: 150 "Foreign key constraint is incorrectly formed")
【问题讨论】:
抱歉,它不起作用:Schema::create('firms', function (Blueprint $table) $table->increments('id')->unsigned(); Schema::create ('jobs', function (Blueprint $table) $table->increments('id'); $table->integer('firm_id')->unsigned(); $table->foreign('firm_id')- >references('id')->on('firms'); 这也不起作用:Schema::create('firms', function (Blueprint $table) $table->increments('id'); Schema::create('jobs' , function (Blueprint $table) $table->increments('id'); $table->integer('firm_id'); $table->foreign('firm_id')->references('id')-> on('公司'); 【参考方案1】:在外键的情况下,被引用的和被引用的字段必须具有完全相同的数据类型。
您在users
和firms
中将id
字段创建为有符号 整数。但是,您将两个外键都创建为 无符号 整数,因此键的创建失败。
您需要将unsigned
子句添加到id
字段定义中,或者从外键字段中删除unsigned
子句。
【讨论】:
很好,对我有帮助。 忘记说这很重要的所有其他事情the referenced and referencing fields must have exactly the same data type.
我几乎要上吊了。谢谢老兄。
我遇到了这个错误,我使用了正确的unsignedBigInteger
作为外键,但是这个错误再次出现。我们必须确定enableForeignKeyConstraints
。我用这个Schema::enableForeignKeyConstraints();
【参考方案2】:
用户
收银员转介用户
学生指收银员
此外,在 laravel 中声明外键时,您所引用的所有表都必须位于顶部。在这种情况下,您可以使用“->unsigned()”修饰符..
【讨论】:
你能解释一下这是如何回答这个问题的吗? 如您所见,“用户”表位于顶部,收银员有“外键”,指的是与学生相同的“用户”表。创建迁移时只需保持表格井井有条。【参考方案3】:大多数情况下,由于两个表的数据类型不匹配,会发生这种错误。
主键表和外键表都应该使用相同的数据类型和相同的选项。
例如:
用户
Schema::create('users', function (Blueprint $table)
$table->increments('id');
$table->string('name');
$table->timestamps();
);
订单
Schema::create('orders', function (Blueprint $table)
$table->bigIncrements('id');
$table->bigInteger('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamp('added_on');
);
在上面的例子中,我试图从订单表中为用户表分配外键,但我在订单表中有 bigInteger 数据表,而在用户表中,我有简单的整数。这就是它产生这种错误的原因。
另外,如果你使用了 unsigned()、nullable() 等带有主键或外键的选项,那么你应该在两个地方都使用相同的选项。
【讨论】:
【参考方案4】:我们是餐桌上的人:
Schema::create('villes', function (Blueprint $table)
$table->bigIncrements('idVille'); // bigIncrement(8 bits)
$table->string('nomVille');
$table->timestamps();
);
例如用户表中的外键:
Schema::table('users', function (Blueprint $table)
$table->bigInteger('ville_idVille')->unsigned()->after('tele');
$table->foreign('ville_idVille')->references('idVille')->on('villes');
);
【讨论】:
【参考方案5】:如果您设置引用字段并且具有完全相同的数据类型但存在错误 您可以更改日期迁移文件 只是它的工作
【讨论】:
【参考方案6】:这个答案并不比之前的六个答案好,但它是关于导致laravel-errno-150-foreign-key-constraint-is-incorrectly-formed
的原因以及如何专门针对 laravel 修复的更全面的答案。
1) 拼写:有时,引用的column name
或引用的table name
的拼写错误可能会引发此错误,您不会知道,因为错误跟踪不是很有描述性.
2) 唯一:引用的列必须是唯一的,或者通过在迁移中的列定义中添加 ->primary()
或添加 ->unique()
或添加 ->index()
来建立索引。
3) 数据类型:被引用的和被引用的字段必须具有完全相同的数据类型。这一点怎么强调都不过分。
对于bigincrements
,预期数据类型为bigInteger('column_name')->unsigned();
increments
预期为 integer('column_name')->unsigned();
等。
4) Remnants : 当这个错误发生时并不意味着表没有被迁移,而是被迁移了但是没有设置外键列并且没有添加到migration table
因此运行php artisan migrate:reset
将删除除故障表之外的其他表,因此建议手动删除故障表以避免进一步的错误。
5) Order :这通常是导致此错误的最常见原因,必须在 reference table
之前创建或迁移表 referenced
否则工匠将找不到集成外键的位置.确保迁移过程的顺序重命名迁移文件示例:
2014_10_12_000000_create_users_table.php
和
表B:2014_10_12_100000_create_password_resets_table.php
这表明表 A 将始终在表 B 之前进行更改,我将表 B 重命名为 2014_10_11_100000_create_password_resets_table.php
现在它将在表 A 之前迁移。
6) 启用外键:如果所有其他方法都失败,则在您的迁移代码示例之前的function up()
中添加Schema::enableForeignKeyConstraints();
:
class CreateUsersTable extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::enableForeignKeyConstraints();
Schema::create('users', function (Blueprint $table)
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('users');
要了解更多信息,请参阅 laravel foreign key 和 laravel migrations
提及我在 cmets 中错过的任何修复,谢谢。
【讨论】:
感谢您的详尽解释。第 3 点的第一个要点对我有用!Unique : the referenced column must be unique
- 这在 mysql 中不一定是正确的(请记住,错误消息与 laravel 无关,它来自 MySQL)。此要求曾经适用于 NDB 表类型,v8.0 将 NDB 要求与 innodb 对齐。对于广泛使用的 innodb 表类型,要求是引用的列必须被索引。
如果您想要更全面的可能原因列表,请查看以下 SO 问题:***.com/questions/1457305/…
非常感谢。 #3 像魅力一样工作
订单是我的错误。谢谢。【参考方案7】:
对于 PHP laravel 5.8,使用这种格式的无符号修饰符
$table->unsignedBigInteger('user_id');
删除数据库中的所有表并再次运行迁移
【讨论】:
注意:在外键中引用的迁移表似乎必须已经创建。否则,我会得到“errno 150 外键约束格式不正确”。【参考方案8】:如果参考表主键在 BigIcrements 中,则使用 BigInteger 作为外键,如下所示
表 ATable
public function up()
Schema::create('a_tables', function (Blueprint $table)
$table->bigIncrements('id');
表 BTable
public function up()
Schema::create('b_tales', function (Blueprint $table)
$table->bigIncrements('id');
$table->bigInteger('a_tables_id')->unsigned();
$table->foreign('a_tables_id')->references('id')->on('a_tables')->onDelete('cascade');
【讨论】:
【参考方案9】:public function up() Schema::create('companies', function (Blueprint $table) $table->bigIncrements('id'); $table->string('name'); $table->text('address'); $table->string('tel1'); $table->string('tel2'); $table->integer('owner'); $table->unsignedBigInteger('access_id'); $table->string('depot_number')->default(2); $table->timestamps(); $table->foreign('access_id')->references('id')->on('accesses') ->onDelete('cascade'); );
public function up() Schema::create('accesses', function (Blueprint $table) $table->bigIncrements('id'); $table->string('type'); $table->string('description'); $table->timestamps(); );
在您的 database/migrations 文件夹中,按名称排序。然后确保 create_accesses_table 在 create_companies_table 之前:
【讨论】:
【参考方案10】:我尝试了此线程中提供的所有答案。
没有任何效果。
然后我发现我忘了删除 phpMyadmin 中的“迁移”表。
我从 phpMyAdmin 中删除了所有表,但迁移表除外。这就是为什么错误一次又一次地持续存在的原因。
【讨论】:
【参考方案11】:这个答案与 Laravel 7.x 有关。所以报错:
errno: 150 "外键约束格式不正确"
在迁移迁移时可能由于多种原因而发生。我熟悉的一个常见原因是迁移顺序。
假设我们有两个表“users”和“roles”,并且“users”表有一个外键引用“roles”表上的“id”列。所以请确保“角色”在“用户”表之前迁移。
所以迁移的顺序很重要。这很明显,因为 MySQL 引用未知表的“id”列是没有意义的。
第二个原因是错误的数据类型。在 laravel 7.x 中,我们使用“id()”方法作为主键。所以请确保预期的外键(在我的情况下是“users”表中的“role_id”)是“bigInteger”并且是“unsigned”。
这是我的代码:
Schema::create('roles', function (Blueprint $table)
$table->id();
$table->string('name');
$table->string('slug')->nullable();
$table->timestamps();
);
Schema::create('users', function (Blueprint $table)
$table->id();
$table->bigInteger("role_id")->unsigned();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
);
public function down()
Schema::table('users', function(Blueprint $table)
$table->dropForeign('users_role_id_foreign');
);
Schema::dropIfExists('users');
所以在上面的代码中,我必须先迁移“角色”表,然后迁移“用户”表。所以 MySQL 可以为角色表创建外键。
我将子迁移(具有外键的迁移)移动到临时文件夹。并在迁移父迁移后恢复它(在我的情况下是“角色”表,然后迁移子迁移(“用户”迁移)。
作为小贴士:在删除依赖迁移(包含外键的迁移)时,首先删除外键。 Laravel 在删除外键“
编码愉快,准备好迎接 PHP 8 的开创性发布。
【讨论】:
感谢您,真正让它点击的地方是意识到在调用伪造密钥表时需要在之前迁移它。呃! ty【参考方案12】:这里的主要概念是您必须确保主键和外键类型相同。例如,让您的第一个表迁移
public function up()
Schema::create('chapters', function (Blueprint $table)
$table->id();
$table->string('title');
$table->timestamps();
);
那么你的第二个表迁移将是
public function up()
Schema::create('classifications', function (Blueprint $table)
$table->id();
$table->string('title');
$table->unsignedBigInteger('chapter_id');
$table->timestamps();
$table->foreign('chapter_id')->references('id')->on('chapters')->onDelete('cascade');
);
这里“chapter”表中的“id”和“classifications”表中的“chapter_id”相同,即“unsignedBigInteger”。
再次,如果您遇到错误,则将“章节”表中的“$table->id();”更改为“$table->bigIncrements('id');”。
希望对你有帮助
【讨论】:
【参考方案13】:对于 laravel 7 的迁移错误为
("SQLSTATE[HY000]: 一般错误: 1005 无法创建表laraveltesting
.reviews
(errno: 150 "外键约束格式不正确")")
迁移顺序是最重要的,因此应先迁移父表,然后再迁移子表 图一:migration order while getting error
Schema::create('products', function (Blueprint $table)
$table->id();
$table->string('name');
$table->text('detail');
$table->float('price');
$table->integer('stock');
$table->float('discount');
$table->timestamps();
);
Schema::create('reviews', function (Blueprint $table)
$table->id();
$table->foreignId('product_id')->constrained('products')->cascadeOnDelete();
$table->string('customer');
$table->text('review');
$table->integer('star');
$table->timestamps();
);
这会导致迁移时出现错误,这可以通过更改迁移顺序来解决,方法是从图像 1 重命名迁移,如图 2 所示。应该首先迁移书籍表,然后只迁移评论表
图片2:Order of migration for the successful migration
【讨论】:
【参考方案14】:如果你得到错误改变 $table->id()(references) by $table->increments('id')
【讨论】:
【参考方案15】:经过所有努力与我合作
从数据库和(迁移表)删除(用户表)然后“取消注释”您的外键关系 示例:
$table->string('pass1');
$table->foreign('pass1')->references('email')->on('abs');
然后运行: php artisan migrate
顺利运行
【讨论】:
以上是关于laravel errno 150 外键约束格式不正确的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 抛出 errno:150 “外键约束的格式不正确”,尽管语法正确
laravel 8 (errno: 150 "外键约束格式不正确")
MySQL创建表:错误1005 errno:150“外键约束形成错误”
一般错误:1005 无法创建表 errno:150“外键约束格式不正确”)