不能在mysql中添加外键?

Posted

技术标签:

【中文标题】不能在mysql中添加外键?【英文标题】:can't add foreign key in 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”操作,(也许工作台添加它?我很困惑)。 我也有同样的问题,直接在服务器上测试后,我只能向你保证它不是工作台。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

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

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

    如果相关列没有完全相同的数据类型(例如 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 提出的三个问题)是您没有将要引用的列设为主键。

【讨论】:

以上是关于不能在mysql中添加外键?的主要内容,如果未能解决你的问题,请参考以下文章

mysql中添加外键问题,求高手

mysql外键建立不起来

无法在 mysql Workbench 中添加外键用户表

mysql为啥被设了外键的表还能被删掉?

数据库添加外键错误:[Err] 1215 - Cannot add foreign key constraint 的解决

mysql添加外键