mysql外键约束错误形成错误

时间:2011-12-08 16:47:34

标签: mysql sql heidisql

我有两个表,当我放入FK时,table1是包含列IDtable2的父表,列IDFromTable1(不是实际名称)在IDFromTable1的{​​{1}}到ID上,我收到错误table1。如果Foreign key constraint is incorrectly formed error记录被删除,我想删除表2记录。谢谢你的帮助

table1

如果需要任何其他信息,请与我们联系。我是mysql的新手

34 个答案:

答案 0 :(得分:286)

我遇到了与HeidiSQL相同的问题。你收到的错误非常神秘。我的问题最终是外键列和引用列的类型或长度不同。

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

答案 1 :(得分:36)

使用MyISAM引擎创建父表时遇到了同样的问题。这是一个愚蠢的错误,我修正了:

ALTER TABLE parent_table ENGINE=InnoDB;

答案 2 :(得分:18)

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

答案 3 :(得分:17)

定义外键的语法是非常宽容的,但对于其他任何人来说,外键必须是“相同类型”的事实甚至适用于整理,而不仅仅是数据类型和长度以及位签名。< / p>

不是说您在模型中混合了排序规则(不是吗?)但是如果这样做,请确保您的主键和外键字段在phpmyadmin或Heidi SQL或您使用的任何内容中具有相同的排序规则类型。

希望这可以为您节省四个小时的试用和错误。

答案 4 :(得分:10)

刚刚完成。

如果您使用VARCHAR(..)的外键并且引用表的字符集与引用它的表不同,则此错误也可能就是这种情况。

e.g。 Latin1表中的VARCHAR(50)与UTF8表中的VARCHAR(50)不同。

答案 5 :(得分:10)

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

只需确保'table1'中的列'ID'具有 UNIQUE 索引!

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

答案 6 :(得分:7)

mysql错误文本没有那么多帮助,在我的情况下,列有“非null”约束,因此不允许“on delete set null”

答案 7 :(得分:4)

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

如果不起作用,请检查两个字段的数据类型。他们必须是一样的。

答案 8 :(得分:3)

对于任何遇到此问题的人,只需运行 SHOW ENGINE INNODB STATUS 并请参见最新外键错误部分。

答案 9 :(得分:3)

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

答案 10 :(得分:3)

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

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

希望这有助于某人。

答案 11 :(得分:2)

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

例如

  

TBL   名称|数据   TYPE |   整理

     

ActivityID | INT |   的 latin1_general_ci   ActivityID | INT |   的 utf8_general_ci

尝试将其更改为

  

TBL   名称|数据   TYPE |   整理

     

ActivityID | INT |   的 latin1_general_ci   ActivityID | INT |   的 latin1_general_ci

...

这对我有用。

答案 12 :(得分:2)

虽然其他答案非常有帮助,但也想分享我的经验。

当我删除了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`); 已在其他表( with data )中被引用为外键的表并尝试使用某些表重新创建/导入表时,我遇到了问题其他专栏。

娱乐查询(在phpMyAdmin中生成)如下所示:

PRIMARY KEY

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

解决方案

解决方案是在id的表定义查询中添加ALTER TABLE索引,该{1}}被引用为外键,同时也将其从索引所在的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; 部分中删除设置:

{{1}}

答案 13 :(得分:1)

我的情况是我在所引用的列上有错字:

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

答案 14 :(得分:1)

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

adding index to table Heidisql

答案 15 :(得分:1)

我为此丢了几个小时!

一张表中的PK为utf8,另一张为utf8_unicode_ci

答案 16 :(得分:1)

尝试运行以下内容:

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;

答案 17 :(得分:1)

您需要检查其所有属性是否相同,包括&#34;整理&#34;

答案 18 :(得分:1)

我在使用Alter表在两个表之间添加外键时遇到了问题,帮助我的事情是确保我尝试添加外键关系的每个列都已编入索引。要在PHP myAdmin中执行此操作: 转到表格并单击结构选项卡。 单击索引选项以索引所需的列,如屏幕截图所示:

enter image description here

一旦我将两个列编入索引,我试图用我的外键引用,我就能够成功使用alter table并创建外键关系。您将看到列的索引类似于以下屏幕截图:

enter image description here

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

答案 19 :(得分:1)

谢谢S Doerin:

&#34;只是为了完成。 如果您的外键具有VARCHAR(..)并且引用的表的字符集与引用它的表不同,则此错误也可能是这种情况。 例如Latin1表中的VARCHAR(50)与UTF8表中的VARCHAR(50)不同。&#34;

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

添加下一行。 DEFAULT CHARACTER SET = utf8;

答案 20 :(得分:1)

我遇到了同样的问题。

问题是引用列不是主键。

将其作为主键并解决问题。

答案 21 :(得分:1)

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

答案 22 :(得分:1)

我对Symfony 2.8也有同样的问题。

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

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

app/console doctrine:cache:clear-metadata app/console doctrine:cache:clear-query app/console doctrine:cache:clear-result

答案 23 :(得分:0)

我刚才遇到了同样的问题。就我而言,我要做的就是确保我在外键中引用的表必须在当前表之前创建(在代码的前面)。因此,如果您引用的是变量(x * 5),则系统应该知道x是什么(x必须在前面的代码行中声明)。这解决了我的问题,希望对您有所帮助。

答案 24 :(得分:0)

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

答案 25 :(得分:0)

我遇到了同样的错误,我发现在我自己的情况下,一张表是 MyISAM,另一张是 INNO。一旦我将 MyISAM 表切换到 INNO。它解决了这个问题。

答案 26 :(得分:0)

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

问题是我在设置列时输入了unigned而不是unsigneds字母丢失了)。

修复拼写错误后,我确定了错误。

答案 27 :(得分:0)

当您在其中引用外键表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

答案 28 :(得分:0)

问题很容易解决

例如:您有两个名称分别为 users posts 的表,并且您想在 posts 中创建外键表格,然后使用 phpMyAdmin

1)在帖子表中添加新列名称:use_id | 类型:类似于 user 表中的 id | 长度 :类似于 user 表中的 id | 默认:NULL | 属性:无符号|索引:INDEX)

2)在结构标签上,转到关系视图约束名称:由phpmyAdmin自动设置| 列名称:选择user_id | :用户| :id ,...)

简单地解决了

javad mosavi伊朗/ urmia

答案 29 :(得分: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的数据类型必须为增量

答案 30 :(得分:0)

这是一个古老的话题,但我发现了一些东西。在构建MySQL工作台时,它还获得了另一个表的关系。只需离开与您相关的支柱即可。清除其他自动添加的列。这对我有用。

答案 31 :(得分:0)

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

enter image description here

答案 32 :(得分:0)

检查您是否在正确的情况下指定了表的名称(如果表名在数据库中区分大小写)。在我的情况下,我不得不改变

 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

答案 33 :(得分:0)

即使我遇到了与mysql和liquibase相同的问题。     所以这就是问题所在:     您要引用其他表的列的表在数据类型或数据类型的大小方面是不同的。

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.