创建外键的问题
Posted
技术标签:
【中文标题】创建外键的问题【英文标题】:Issues with creating a foreign key 【发布时间】:2014-11-19 05:58:04 【问题描述】:我在设置两个名为 Customer
和 Customer_Number
的表之间的关系时遇到问题。我将两个表都设置为InnoDB
都有索引,但是当我去创建外键时,我得到一个“没有定义索引”的错误。以下是部分截图
这是客户表。
这是 Customer_Number 表。
这是我在尝试创建外键时的错误消息。
最后,这是我在尝试手动创建关系时遇到的错误。
我似乎无法弄清楚这个问题,这让我发疯了!
SHOW CREATE TABLE Customer
的输出是
CREATE TABLE `Customer` (
`Customer_ID` int(11) NOT NULL AUTO_INCREMENT,
`First` varchar(255) NOT NULL,
`Last` varchar(255) NOT NULL,
PRIMARY KEY (`Customer_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
SHOW CREATE TABLE Customer_Number
的输出是
CREATE TABLE `Customer_Number` (
`Num_ID` int(11) NOT NULL AUTO_INCREMENT,
`Customer_ID` int(11) NOT NULL,
`Number` varchar(255) NOT NULL,
PRIMARY KEY (`Num_ID`),
KEY `Customer_ID` (`Customer_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
【问题讨论】:
@MichaelBerkowski 更新了所要求的信息 嗯,我实际上没有问题创建这些表,然后添加 FK,或者在原始定义中使用 FK 创建它们。这有效:ALTER TABLE Customer_Number ADD FOREIGN KEY (Customer_ID) REFERENCES Customer (Customer_ID);
嗯,当我把你给我的东西放进去时,我得到了这个错误#1452 - Cannot add or update a child row: a foreign key constraint fails (
thesnoopz.
#sql-23d7_8c3428, CONSTRAINT
#sql-23d7_8c3428_ibfk_1` FOREIGN KEY (@9876543765@) 3739参考文献@ (Customer_ID
)) `
哦,看来您可能已经在 Customer_Number.Customer_ID
中的某些行中有一个值,而在 Customer.Customer_ID
中没有相应的父行。为了创建 FK,任何已经存在的值都必须是对 Customer
父表的有效行引用。
SELECT * FROM Customer_Number WHERE Customer_ID NOT IN (SELECT Customer_ID FROM Customer)
看看是不是这样。
【参考方案1】:
请试试这个。
alter table Customer_Number add foreign key(customer_ID) references Customer (Customer_ID);
【讨论】:
【参考方案2】:发布的两个CREATE TABLE
语句是正确的,并且应该能够接受Customer_Number.Customer_ID
上的新FOREIGN KEY
约束,因为满足必要的条件(与引用的列相同的数据类型、可比较的索引或引用的主键列)。
ALTER
语句在我的测试中成功:
ALTER TABLE Customer_Number ADD FOREIGN KEY (Customer_ID) REFERENCES Customer (Customer_ID);
由于不熟悉 phpMyAdmin 如何抽象出一些 RDBMS 错误,因此很难确定 GUI 中究竟出了什么问题。但是,如果您手动运行ALTER
语句并遇到有关失败的外键约束的错误,这表明引用表已经包含列中的值,这些值不引用父表中的有效行值。要发现这些行以便解决它们,请执行如下查询:
SELECT * FROM Customer_Number WHERE Customer_ID NOT IN (SELECT Customer_ID FROM Customer)
找到有问题的行后,您可以删除它们(如果不需要)或将它们的值更新为引用表中有效行值的值。如果列的定义允许NULL
(您的不允许),您也可以UPDATE
将它们设置为NULL
,然后再次运行ALTER
语句。
还可以暂时禁用外键检查,添加约束,更新行以匹配有效的父表值,重新启用外键检查。
【讨论】:
以上是关于创建外键的问题的主要内容,如果未能解决你的问题,请参考以下文章