不能在mysql中添加外键?

时间:2011-04-22 17:22:25

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

我使用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

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

10 个答案:

答案 0 :(得分:16)

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

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

答案 1 :(得分:10)

可能因为很多原因而发生。以下是一些常见原因。你也可以说语法错误,因为这会引发这类错误。

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

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

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

答案 2 :(得分:5)

当使用MyISAM存储将链接到(在您的情况下为Goods)的表时,以及您要添加索引的表(在您的情况下,声明中),我收到此错误)使用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操作成功完成。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

因人而异。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

Errno 150有很多原因。如果您拥有超级特权,则应尝试使用

SHOW ENGINE INNODB状态

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

MySQL Foreign Key Errors and Errno 150

答案 9 :(得分:0)

第四个可能的问题(abhijitcaps提出的三个问题)是你没有使你引用主列的列。