13

我使用 MySQL 工作台在表中添加外键,但发生了一些奇怪的错误,这是 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

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

4

10 回答 10

16

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

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

于 2012-03-20T20:14:59.983 回答
10

它可能由于许多原因而发生。以下是一些常见的原因。您也可以说语法错误,因此会引发这些类型的错误。

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

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

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

于 2013-05-22T03:23:34.873 回答
5

当链接到的表(在您的情况下为货物)使用 MyISAM 存储时,我收到此错误,而您添加索引的表(在您的情况下为声明)使用 InnoDB 存储。

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

table_name.frm
table_name.MYD
table_name.MYI

InnoDB 表将只有:

table_name.frm

MyISAM 不支持外键约束。我建议将您的 Goods 表转换为 InnoDB(不过,请先查看文档并进行一些基础研究):

ALTER TABLE Goods ENGINE=INNODB;

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

于 2011-09-28T10:58:03.337 回答
1

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

于 2013-01-16T15:54:11.430 回答
1

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

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

YMMV。

于 2015-05-09T15:17:56.647 回答
0

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

显示引擎 INNODB 状态

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

MySQL 外键错误和 Errno 150

于 2012-06-15T18:01:24.717 回答
0

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

DELETE FROM books
WHERE NOT EXISTS (
    SELECT * FROM users
    WHERE books.user_id = users.id
)
于 2012-04-21T12:50:22.573 回答
0

Goods.goodsId和的类型定义Declarations.goodsId必须相同,否则您将得到errno: 150.

确保它们都是相同的数据类型,看起来goodsId INT(11) NOT NULLDeclarations表中。CREATE TABLE声明是为了Goods什么?

于 2011-04-22T17:40:56.550 回答
0

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

于 2014-08-01T09:21:38.463 回答
0

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

于 2012-05-20T09:43:02.357 回答