【问题标题】:mysql Foreign key constraint is incorrectly formed errormysql外键约束格式错误
【发布时间】:2012-01-16 02:20:50
【问题描述】:

我有两个表,table1 是父表,其列 IDtable2IDFromTable1(不是实际名称)当我在 IDFromTable1ID 上放置 FK 时在table1 我收到错误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 新手

【问题讨论】:

  • 您的表格使用什么引擎? table2.IDFromTable1table1.ID是什么类型的?
  • 另外,检查两个表的字符集是否相同。
  • 两个表引擎都是innoDB。不知道在哪里可以找到字符集,而且都是 char 类型。 ID是table1中的主键
  • 请提供 table1 和 table2 的表定义。你是怎么得到这个错误的?您是否使用工具来创建外键?好像不是 MySQL 原生错误。
  • @user516883 - 您需要帮助来获取表定义吗?在 HeidiSQL 中,您只需单击 CREATE code 选项卡即可。

标签: mysql sql heidisql


【解决方案1】:

如果 U 表是 Myisum 而新表是 InoDb 你是注意 Foreign 您必须将 MyIsum 表更改为 InoDb

【讨论】:

    【解决方案2】:

    mysql 错误文本没有多大帮助,在我的情况下,该列有“not null”约束,因此不允许使用“on delete set null

    【讨论】:

    • 上帝保佑你。我已经为此苦苦挣扎了将近一个小时。
    • 我问自己——当我在这样神秘的错误信息中挣扎时——谁在提出错误信息。可能有一个上下文谁可以创建最神秘和误导性的错误消息。谢谢!我在表格设计中就遇到了这个问题。
    【解决方案3】:

    对于像我一样在这个问题上苦苦挣扎的人来说,这是我的问题:

    我试图更改表以将字段从 VARCHAR(16) 更改为 VARCHAR(255),这引用了另一个数据类型仍为 VARCHAR(16) 的表列...

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          对于遇到此问题的任何人,只需运行 SHOW ENGINE INNODB STATUS 并查看最新外键错误部分了解详情。

          【讨论】:

          • 谢谢,它为我节省了几个小时
          • 谢谢,这比在这里尝试所有其他答案有用得多。
          • 绝对!感觉它确实应该是公认的答案,因为它显示了它的实际问题,而不仅仅是列出可能发生这种情况的一两个原因。..
          • 您,先生,为我节省了数小时的时间!非常感谢!
          【解决方案7】:

          当您在引用它的迁移table2 之后具有外键表table1 迁移时,Laravel 也会出现此问题。

          您必须保留迁移的顺序才能使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
          

          【讨论】:

            【解决方案8】:

            这个问题很容易解决

            例如:您有两个名称为 usersposts 的表,并且您想在 posts 中创建 外键表,你使用 phpMyAdmin

            1) 在 post 表中添加 新列 (name:use_id | type:类似于 user 表中的 id | Length :like user 表中的 id | Default:NULL | Attributes:unsigned | index:INDEX )

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

            简单解决了

            javad mosavi 伊朗/urmia

            【讨论】:

              【解决方案9】:

              我遇到了这个问题,当您将主键放入不同的数据类型时出现错误,例如:

              表 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的数据类型必须是increments

              【讨论】:

                【解决方案10】:

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

                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
                

                【讨论】:

                  【解决方案11】:

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

                  【讨论】:

                    【解决方案12】:

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

                    【讨论】:

                    • 我在 MariaDB v10.3.18 中遇到了同样的问题。我们之前使用过 MySQL,它警告说外键指向一个不存在的表。
                    【解决方案13】:

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

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

                    希望这对某人有所帮助。

                    【讨论】:

                    • 其实是 FOREIGN_KEY_CHECKS
                    • 这确实帮助我进一步通过,但我的问题是缺少列中的主索引
                    • 我在删除具有外键约束的表并尝试重新创建表和外键后遇到此问题。奇怪的是,phpMyAdmin 告诉我外键也被删除了,但是当我运行我的创建查询时,MySQL 仍然抛出这个错误,就好像它仍然存在一样。重新启动 MySQL,然后设置 FOREIGN_KEY_CHECKS=OFF 修复了我的边缘情况的任何错误,允许我再次创建表。
                    • 这只适用于其中一张表,其余的我仍然得到同样的错误。我假设有一些我不知道的元数据列或大写?
                    • 确实有帮助!我必须导入多年前创建的 3GB 数据库,而 FOREIGN_KEY_CHECKS=OFF 成功了!谢谢你!
                    【解决方案14】:

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

                    举例

                        TBL 姓名       |数据 类型          | 整理        

                        ActivityID          | INT                        | latin1_general_ci 活动 ID          | INT                        | utf8_general_ci

                    试试改成

                        TBL 姓名       |数据 类型          | 整理        

                        ActivityID          | INT                        | latin1_general_ci 活动 ID          | INT                        | latin1_general_ci

                    ....

                    这对我有用。

                    【讨论】:

                      【解决方案15】:

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

                      【讨论】:

                        【解决方案16】:

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

                        【讨论】:

                        • 拯救我的一天~~~~ 非常感谢
                        【解决方案17】:

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

                         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

                        【讨论】:

                          【解决方案18】:

                          我为此输了好几个小时!

                          一张桌子的PK是utf8,另一张桌子是utf8_unicode_ci

                          【讨论】:

                            【解决方案19】:

                            即使我在使用 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.
                            

                            【讨论】:

                              【解决方案20】:

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

                              【讨论】:

                              • 我在 mysql 中也是如此:InnoDB 需要外键和引用键上的索引,以便外键检查可以快速且不需要表扫描。
                              【解决方案21】:

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

                              【讨论】:

                              • 好点!我正在处理 MySQL 中的 Zen Cart 数据库,默认情况下,它的表都在 MyISAM 引擎中。我使用 InnoDB 引擎添加了一个表,并尝试将我的表中的外键约束添加到核心 Zen Cart 中。它因这个晦涩的“格式不正确”错误而失败。您可以使用 SHOW TABLE STATUS LIKE 'table_name'; 查看每个表的引擎
                              【解决方案22】:

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

                              我在删除一个表时遇到了这个问题,该表的 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;
                              

                              【讨论】:

                              • 它对我有用。我担心我需要重新安装我的软件;)
                              【解决方案23】:

                              您需要检查其所有属性是否相同,包括“排序规则”

                              【讨论】:

                                【解决方案24】:

                                我也有同样的问题。

                                问题是引用列不是主键。

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

                                【讨论】:

                                • 不一定是PK,也可以是UNIQUE NOT NULL。
                                • 实际上......在我的情况下,只需将其设置为正常工作的索引类型。
                                【解决方案25】:

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

                                一旦我索引了我试图用外键引用的两列,我就能够成功地使用更改表并创建外键关系。您将看到列的索引如下图所示:

                                注意 zip_code 在两个表中的显示方式。

                                【讨论】:

                                  【解决方案26】:

                                  感谢 S Doerin:

                                  “只是为了完成。 如果您有一个带有 VARCHAR(..) 的外键并且被引用表的字符集与引用它的表不同,则可能会出现此错误。 例如Latin1 表中的 VARCHAR(50) 与 UTF8 表中的 VARCHAR(50) 不同。"

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

                                  添加下一行。 默认字符集 = utf8;

                                  【讨论】:

                                  • 这也是我的情况。 Varchar 类型的排序规则不同,只要我使用 phpMyAdmin Client 更改排序规则,一切正常
                                  【解决方案27】:

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

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

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

                                  【讨论】:

                                  • 你成就了我的一天。
                                  • 很高兴为您提供帮助! ;)
                                  • 不确定细节,但我有一个复合键出现此错误,已通过为列添加单独的唯一索引来修复。
                                  • 被引用的列必须被索引,它不必是唯一的(虽然这是通常的情况)。
                                  【解决方案28】:

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

                                  【讨论】:

                                  • 我什至碰巧,没有错误,但是没有添加外键(1是,1实际上没有),而是添加了简单的KEY referencing_column(referencing_column)BEFORE i> 两个外键定义都成功添加了:)
                                  • 没有被索引的键是我的问题。
                                  • 我遇到了这个问题,问题是我有一个双列主键,您不能将主键的第二列用作外键。所以我只是为主键的第二列添加了自己的索引,然后它就起作用了。
                                  【解决方案29】:

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

                                  如果它不起作用,请检查两个字段的数据类型。它们必须相同。

                                  【讨论】:

                                  • 在我的情况下,“检查两个字段的数据类型。它们必须相同”是我的解决方案。谢谢你,@josef :)
                                  【解决方案30】:

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

                                  一开始没搞懂,因为外键的int长度等没有类似的问题。

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

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

                                  【讨论】:

                                    猜你喜欢
                                    • 2020-02-19
                                    • 2021-03-01
                                    • 2018-09-15
                                    • 2023-03-13
                                    • 2018-02-15
                                    • 2018-09-04
                                    • 1970-01-01
                                    • 2019-08-08
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多