不能在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.goodsId
和Declarations.goodsId
的类型定义必须相同,否则会得到errno: 150
。
确保它们都是相同的数据类型,在Declarations
表中看起来是goodsId INT(11) NOT NULL
。 Goods
的 CREATE 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中添加外键?的主要内容,如果未能解决你的问题,请参考以下文章
数据库添加外键错误:[Err] 1215 - Cannot add foreign key constraint 的解决