mysql外键约束不正确错误

我有两个表,table1是父表,有一个列IDtable2,有一个列IDFromTable1(不是实际名称),当我在table1中对IDFromTable1ID进行FK时,我得到了错误Foreign key constraint is incorrectly formed error。如果table1记录被删除,我想删除表2记录。谢谢你的帮助

ALTER TABLE `table2`
ADD CONSTRAINT `FK1`
FOREIGN KEY (`IDFromTable1`) REFERENCES `table1` (`ID`)
ON UPDATE CASCADE
ON DELETE CASCADE;

如果还需要其他信息,请告诉我。我是mysql的新手

565251 次浏览

试着运行以下命令:

show create table Parent


//and check if type for both tables are the same, like myISAM or innoDB, etc
//Other aspects to check with this error message: the columns used as foreign
keys must be indexed, they must be of the same type
(if i.e one is of type smallint(5) and the other of type smallint(6),
it won't work), and, if they are integers, they should be unsigned.


//or check for charsets
show variables like "character_set_database";
show variables like "collation_database";


//edited: try something like this
ALTER TABLE table2
ADD CONSTRAINT fk_IdTable2
FOREIGN KEY (Table1_Id)
REFERENCES Table1(Table1_Id)
ON UPDATE CASCADE
ON DELETE CASCADE;

我在使用HeidiSQL时也遇到了同样的问题。您收到的错误非常神秘。我的问题是外键列和引用列的类型或长度不相同。

外键列是SMALLINT(5) UNSIGNED,引用列是INT(10) UNSIGNED。一旦我将它们都设置为完全相同的类型,外键的创建就会完美地工作。

定义外键的语法是非常宽容的,但对于任何其他人来说,外键必须“具有相同类型”的事实甚至适用于排序,而不仅仅是数据类型、长度和位签名。

并不是说你会在你的模型中混合排序规则(你会吗?),但如果你这样做了,确保你的主键和外键字段在phpmyadmin或Heidi SQL或其他你使用的工具中具有相同的排序规则类型。

希望这能帮你省下我花在试错上的4个小时。

我在Laravel 5.1迁移Schema Builder到MariaDB 10.1时也遇到了同样的问题。

问题是我在设置列时键入了unigned而不是unsigned(缺少s字母)。

修复后,错别字为我修复。

当使用MyISAM引擎创建父表时,我有同样的问题。这是一个愚蠢的错误,我用:

ALTER TABLE parent_table ENGINE=InnoDB;

只是为了完成。

如果你有一个VARCHAR(..)外键,并且被引用的表的字符集与引用它的表的字符集不同,也可能会出现这个错误。

例如,Latin1表中的VARCHAR(50)与UTF8表中的VARCHAR(50)不同。

我在Symfony 2.8上也遇到了同样的问题。

我一开始没有得到它,因为外键的int长度等没有类似的问题。

最后,我必须在项目文件夹中执行以下操作。(服务器重启不起作用!)

< p > <代码> app /控制台学说:缓存:clear-metadata 应用程序/控制台学说:缓存:clear-query app /控制台学说:缓存:明确的结果代码< / > < / p >

如果一切正常,只需在foregin key后面添加->unsigned();

如果不行,请检查两个字段的数据类型。它们必须是一样的。

确保列是相同的(相同类型),如果引用列不是primary_key,则确保它是INDEXED

mysql错误文本没有多大帮助,在我的情况下,列有"not null"约束,所以"on delete set null"不被允许

我也有同样的问题,但我解决了。

只要确保列'ID'在'table1'有UNIQUE索引!

当然,这两个表中'ID'和'IDFromTable1'的列的类型和长度必须相同。但是你已经知道了。

我也有同样的问题。

问题是参考列不是主键。

把它设为主键,问题就解决了。

谢谢S Doerin:

"只是为了完成。 如果你有一个VARCHAR(..)外键,并且被引用的表的字符集与引用它的表的字符集不同,也可能会出现这个错误。 例如,Latin1表中的VARCHAR(50)与UTF8表中的VARCHAR(50)不同。" < / em > < / p >

我解决了这个问题,改变了表的字符类型。 创建了latin1,正确的是utf8.

添加下一行。

.默认字符集= utf8

我有问题使用Alter表在两个表之间添加外键,帮助我的是确保我试图添加外键关系的每列都被索引。在PHP myAdmin中这样做: 转到表并单击结构选项卡。

.单击索引选项,为所需要的列建立索引,如图截图所示

enter image description here

一旦我索引了我试图用外键引用的两列,我就能够成功地使用alter表并创建外键关系。你会看到列的索引如下面的截图:

enter image description here

注意zip_code是如何在两个表中显示的。

虽然其他的答案都很有帮助,但我也想分享一下我的经验。

当我删除了一个表,它的id已经在其他表(与数据)中被引用为外键时,我遇到了这个问题,并试图用一些额外的列重新创建/导入表。

用于重新创建的查询(在phpMyAdmin中生成)如下所示:

CREATE TABLE `the_table` (
`id` int(11) NOT NULL,            /* No PRIMARY KEY index */
`name` varchar(255) NOT NULL,
`name_fa` varchar(255) NOT NULL,
`name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


... /* SOME DATA DUMP OPERATION */


ALTER TABLE `the_table`
ADD PRIMARY KEY (`id`), /* PRIMARY KEY INDEX */
ADD UNIQUE KEY `uk_acu_donor_name` (`name`);

正如你可能注意到的,PRIMARY KEY索引是在创建(数据的插入)之后设置的,这导致了问题。

解决方案

解决方案是在表定义查询中为被引用为外键的id添加PRIMARY KEY索引,同时将其从设置索引的ALTER TABLE部分中删除:

CREATE TABLE `the_table` (
`id` int(11) NOT NULL PRIMARY KEY,            /* <<== PRIMARY KEY INDEX ON CREATION */
`name` varchar(255) NOT NULL,
`name_fa` varchar(255) NOT NULL,
`name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

检查表格引擎,两个表格必须是相同的引擎,这对我帮助很大。

我正在使用HeidiSQL,为了解决这个问题,我必须引用所有列在引用表中创建索引

adding index to table Heidisql

甚至我也遇到了mysql和libase同样的问题。 这就是问题所在: 要引用其他表的列的表在数据类型或数据类型大小方面都是不同的
Error appears in below scenario:
Scenario 1:
Table A has column id, type=bigint
Table B column referenced_id type varchar(this column gets the value from the id column of Table A.)
Liquibase changeset for table B:


<changeset id="XXXXXXXXXXX-1" author="xyz">
<column name="referenced_id" **type="varchar"**>
</column>
</changeset>
<changeSet id="XXXXXXXXXXX-2" author="xyz">
<addForeignKeyConstraint constraintName="FK_table_A"
referencedTableName="A" **baseColumnNames="referenced_id**"
referencedColumnNames="id" baseTableName="B" />
</changeSet>


Table A changeSet:


<changeSet id="YYYYYYYYYY" author="xyz">
<column **name="id"** **type="bigint"** autoIncrement="${autoIncrement}">
<constraints primaryKey="true" nullable="false"/>
</column>
</changeSet>


Solution:
correct the type of table B to bigint because the referenced table has type bigint.


Scenrario 2:
The type might be correct but the size might not.
e.g. :
Table B : referenced column type="varchar 50"
Table A : base column type ="varchar 255"


Solution change the size of referenced column to that of base table's column size.

我为这个损失了好几个小时!

一个表中的PK为utf8,另一个表中的PK为utf8_unicode_ci!

我有同样的问题,两列都是INT(11) NOT NULL,但我不能创建外键。 我必须禁用外键检查才能成功运行:

SET FOREIGN_KEY_CHECKS=OFF;
ALTER TABLE ... ADD CONSTRAINT ...
SET FOREIGN_KEY_CHECKS=ON;

希望这能帮助到一些人。

检查是否以正确的大小写指定了表名(如果数据库中的表名是区分大小写的)。就我而言,我必须改变

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `CUSTOMER` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

注意customer变成了CUSTOMER

显示此错误的另一个可能原因。我创建表的顺序是错误的。我试图从一个尚未创建的表中引用一个键。

或者您可以使用DBDesigner4,它具有图形界面来创建数据库并使用FK链接它们。右键单击您的表并选择“复制表SQL创建”,这将创建代码。

enter image description here

即使字段名和数据类型相同,但排序规则不相同,也会导致该问题。

例如

< p >,,,资源描述 NAME ,,,,,, |,,,,,,,,的数据 TYPE ,,,,,,,, | ,,,,,,, COLLATION ,,,,,,, < / p > < p >,,,, ActivityID ,,,,,,,,, |,,,,,,,, INT ,,,,,,,,,,,,,,,,,,,,,, | ,,,,,, latin1_general_ci ,,, ActivityID ,,,,,,,,, |,,,,,,,, INT ,,,,,,,,,,,,,,,,,,,,,, | ,,,,,,, utf8_general_ci < / p >

试着把它变成

< p >,,,资源描述 NAME ,,,,,, |,,,,,,,,的数据 TYPE ,,,,,,,, | ,,,,,,, COLLATION ,,,,,,, < / p > < p >,,,, ActivityID ,,,,,,,,, |,,,,,,,, INT ,,,,,,,,,,,,,,,,,,,,,, | ,,,,,, latin1_general_ci ,,, ActivityID ,,,,,,,,, |,,,,,,,, INT ,,,,,,,,,,,,,,,,,,,,,, | ,,,,,,, latin1_general_ci < / p >

....

这对我很管用。

我刚才也遇到了同样的问题。在我的例子中,我所要做的就是确保我在外键中引用的表必须在当前表之前创建(在代码的前面)。因此,如果你引用一个变量(x*5),系统应该知道x是什么(x必须在前面的代码行中声明)。这解决了我的问题,希望它能帮助其他人。

我的情况是,我在参考栏上有一个错别字:

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( coutry_code );
ERROR 1005 (HY000): Can't create table `blog`.`t_user` (errno: 150 "Foreign key constraint is incorrectly formed")

错误消息非常神秘,我已经尝试了所有的方法——验证列的类型、排序规则、引擎等。

我花了一段时间才注意到这个错字,修复后一切都很好:

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( country_code );
Query OK, 2 rows affected (0.039 sec)
Records: 2  Duplicates: 0  Warnings: 0

我面临这个问题,当你把主键放在不同的数据类型,比如:

表1:

 Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('product_name');
});

表2:

Schema::create('brands', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('brand_name');
});

第二个表id的数据类型必须是增量

这个问题很容易解决

例:你有两个表,名字分别为用户的帖子,你想在的帖子表中创建外键,你使用phpMyAdmin

1)在帖子表中添加新列 (的名字:use_id | 类型: like the id in 用户 table | 长度:like the id in 用户 table | 默认的:NULL | 属性:unsigned | index: index)

2)在结构选项卡上进入关系视图 (约束的名字: auto set by phpmyAdmin | 列名:select user_id |表格:users | 关键: id,…)

它被简单地解决了

Javad mosavi伊朗/urmia

这个问题也发生在Laravel中,当你有外键表table1迁移后,你引用它的迁移table2

你必须保留迁移的顺序,以便foreign key特性能够正常工作。

database/migrations/2020_01_01_00001_create_table2_table.php
database/migrations/2020_01_01_00002_create_table1_table.php

应该是:

database/migrations/2020_01_01_00001_create_table1_table.php
database/migrations/2020_01_01_00002_create_table2_table.php
对于任何面临这个问题的人,跑吧 SHOW ENGINE INNODB STATUS ,详见最新外键错误部分

我也犯了同样的错误,我发现在我自己的案例中,一张表是MyISAM,另一张是INNO。一旦我把MyISAM表切换到INNO。这解决了问题。

我在这里遗漏的另一个解决方案是,在创建约束的表中,引用表的每个主键都应该有一个带有外键的条目。

对于任何和我一样在这个问题上挣扎的人来说,这就是我的问题:

我试图修改一个表,将字段从VARCHAR(16)更改为VARCHAR(255),这是引用另一个表列,其中数据类型仍然是VARCHAR(16)…

如果U表是Myisum,而新表是InoDb,则您是Note Foreign 你必须将MyIsum表更改为InoDb

事先尝试SET FOREIGN_KEY_CHECKS = 0;