【问题标题】:can't add foreign key in mysql?不能在mysql中添加外键?
【发布时间】:2011-08-11 02:45:48
【问题描述】:

我用 MySQL workbench 在表中添加外键,但出现了一些奇怪的错误,这是 SQL 语句:

ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL  AFTER `declarationId` , 
    ADD CONSTRAINT `goodsId`
        FOREIGN KEY (`goodsId` )
        REFERENCES `tansung`.`Goods` (`goodsId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
    , ADD INDEX `goodsId` (`goodsId` ASC) ;

当我点击应用时,惊喜就出来了!

ERROR 1005: Can't create table 'tansung.#sql-1b10_1' (errno: 150)

SQL Statement:

ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL  AFTER `declarationId` , 
    ADD CONSTRAINT `goodsId`
        FOREIGN KEY (`goodsId` )
        REFERENCES `tansung`.`Goods` (`goodsId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
    , ADD INDEX `goodsId` (`goodsId` ASC)


ERROR: Error when running failback script. Details follow.


ERROR 1050: Table 'Declaration' already exists

SQL Statement:

CREATE TABLE `Declaration` (
    `declarationId` int(11) NOT NULL,
    PRIMARY KEY (`declarationId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我在逻辑上找不到任何错误,甚至无法理解错误,请给我帮助。

【问题讨论】:

  • 这个错误似乎不言自明;您正在尝试创建一个名为 Declaration 的表,该表已经存在...
  • 确保您没有在一个窗口中运行所有 SQL 代码。您似乎正在运行 ALTER TABLE 代码,然后是 CREATE TABLE 代码...确保您只运行 ALTER TABLE 代码以防止出现该错误。
  • @Brian Driscoll 真正的错误出现在代码块的顶部ERROR 1005: Can't create table 'tansung.#sql-1b10_1' (errno: 150)
  • 我只是运行“alter”操作,从不“creat”操作,(也许工作台添加它?我很困惑)。
  • 我也有同样的问题,直接在服务器上测试后,我只能向你保证它不是工作台。

标签: mysql foreign-keys mysql-error-1005


【解决方案1】:

整个数据库中的所有外键名称都必须是唯一的。如果您已经有一个名为“goodsId”的外键,即使在另一个表上,您也会收到此错误。

如果相关列不具有完全相同的类型(例如 INT)和约束(UNIQUE 等),您将收到该错误。

【讨论】:

    【解决方案2】:

    发生这种情况的原因有很多。以下是一些常见的原因。你也可以说语法错误,因此会引发这些类型的错误。

    1. 如果 FK(外键)表引擎正在使用 MyISAM,而 PK(主键)表引擎正在使用 InnoDB。 MyISAM 不支持外键约束。因此,您可能希望将链接表转换为 InnoDB。

    2. 整个数据库中的所有外键名称都必须是唯一的。如果你已经有一个同名的外键约束,即使在另一个表上,你也会收到这个错误。

    3. 如果相关列没有完全相同的数据类型(例如 INT)和约束(UNIQUE 等),您将收到该错误。

    【讨论】:

    • 谢谢 我不知道整个数据库中的所有外键名称都必须是唯一的
    • 欢迎您@Vinay。很高兴答案对您有所帮助。
    • 不匹配的表引擎是我的罪魁祸首。谢谢。
    • 谢谢!这正是我想要的。
    【解决方案3】:

    当链接到 的表(在您的情况下为货物)使用 MyISAM 存储并且您要向其中添加索引的表(在您的情况下为声明) 使用 InnoDB 存储。

    您可以从数据库目录中的文件中看出这一点。 MyISAM 表将包含如下文件:

    table_name.frm
    table_name.MYD
    table_name.MYI
    

    InnoDB 表将只有:

    table_name.frm
    

    MyISAM 不支持外键约束。我建议将您的 Goods 表转换为 InnoDB(不过,请先查看文档并做一些 basic research):

    ALTER TABLE Goods ENGINE=INNODB;
    

    进行此更改后,我的 ADD INDEX 操作成功完成。

    【讨论】:

      【解决方案4】:

      正如其他人所说,首先确保两列的类型相同并且数据库支持它。之后,确保保存其他表的键的列是有效的。 我遇到了一个问题,我将约束添加到其中包含数据的 existing 列,并且该数据与另一个表中的任何主键都不匹配,因此尝试创建关系会失败。修复它涉及更新所有列,以确保我的列数据与我试图制定的约束相匹配。

      【讨论】:

        【解决方案5】:

        我发现当尝试在 phpMyAdmin 中执行此操作时,名称中带有连字符的表只允许一个 FK,然后给出错误。我不知道为什么,但它很容易解决我只是重新制作了

         CREATE TABLE `something_new` LIKE `something-old`;
         DROP TABLE `something-old`;
        

        YMMV。

        【讨论】:

          【解决方案6】:

          Goods.goodsIdDeclarations.goodsId 的类型定义必须相同,否则会得到errno: 150

          确保它们都是相同的数据类型,在Declarations 表中看起来是goodsId INT(11) NOT NULLGoodsCREATE TABLE 语句是什么?

          【讨论】:

          • 可能和我设置的“lower_case_table_names=0”有些关系
          • 因为我需要ORM来生成实体类,所以我想使用upper_case,但是windows中的mysql只取lower_case_table_names,所以我设置lower_case_table_names=0,但是当我这样做时可能会出现一些问题添加外键。
          【解决方案7】:

          我遇到了同样的问题。似乎子表中有一些数据不存在于父表中。您可以进行外部联接以查看差异,您可以为不匹配的行分配有效的 id 或删除它们:

          DELETE FROM books
          WHERE NOT EXISTS (
              SELECT * FROM users
              WHERE books.user_id = users.id
          )
          

          【讨论】:

            【解决方案8】:

            Errno 150 有很多原因。如果你有 SUPER 权限,你应该尝试使用

            显示 ENGINE INNODB 状态

            这会告诉你原因是什么。如果您没有 SUPER 权限,则只需检查所有可能的原因。您可以在此处找到如何使用 SHOW INNODB STATUS 以及所有原因的列表:

            MySQL Foreign Key Errors and Errno 150

            【讨论】:

              【解决方案9】:

              当我收到该错误时,是因为我试图更新一个已经包含数据的表并且数据不符合FK restrictions

              【讨论】:

                【解决方案10】:

                第四个可能的问题(对于 abhijitcaps 提出的三个问题)是您没有将要引用的列设为主键。

                【讨论】:

                  猜你喜欢
                  • 2015-11-20
                  • 2014-09-24
                  • 2019-05-04
                  • 2016-01-05
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-11-12
                  相关资源
                  最近更新 更多