MYSQL:错误:无法添加或更新子行:外键约束失败

时间:2010-04-16 00:50:48

标签: mysql

在Windows操作系统上使用MySQL,尝试在两个表之间创建外键时出错:

CREATE TABLE tf_traffic_stats  ( 
domain_name     char(100) NOT NULL,
session_count   int(11) NULL,
search_count    int(11) NULL,
click_count     int(11) NULL,
revenue         float NULL,
rpm             float NULL,
cpc             float NULL,
traffic_date    date NOT NULL DEFAULT '0000-00-00',
PRIMARY KEY(domain_name,traffic_date))

CREATE TABLE td_domain_name  ( 
domain_id   int(10) UNSIGNED AUTO_INCREMENT NOT NULL,
domain_name char(100) NOT NULL,
update_date date NOT NULL,
PRIMARY KEY(domain_id))

以下语句为我提供了主题行中出现的错误(无法添加或更新子行:外键约束失败):

ALTER TABLE td_domain_name
ADD CONSTRAINT FK_domain_name
FOREIGN KEY(domain_name)
REFERENCES tf_traffic_stats(domain_name)
ON DELETE RESTRICT 
     ON UPDATE RESTRICT

有人能指出我可能导致错误的正确方向。我也有一个引用td_domain_name.domain_id的外键,但我不认为这应该是干扰......

此外,作为此问题的解决方法(失败)(我确信可以轻松解决),我尝试过简单地执行

td_domain_name left outer join tf_traffic_stats on td_domain_name.domain_name=tf_traffic_stats.domain_name

但是,记录的数量不应该匹配(即,左外连接不成功)。

欣赏它!

3 个答案:

答案 0 :(得分:3)

您的td_domain_name.domain_name值没有匹配的tf_traffic_stats.domain_name值。您必须在添加外键约束之前解决此问题。

您可以使用以下查询找到有问题的行:

SELECT td_domain_name.domain_name
FROM td_domain_name LEFT JOIN tf_traffic_stats
  ON td_domain_name.domain_name = tf_traffic_stats.domain_name
WHERE tf_traffic_stats.domain_name IS NULL

答案 1 :(得分:1)

外键可以a lot of reasons产生错误。不幸的是,MySQL对于它的原因并不十分具体。

看起来你已经有了正确的索引,并且你的列类型匹配,所以我的猜测是你在第二个表中有一些数据无法与第一个数据相关联。类似以下查询的内容会向您显示td_domain_nametf_traffic_stats中没有相应域名的所有行:

SELECT * FROM td_domain_name WHERE domain_name NOT IN 
    (SELECT DISTINCT(domain_name) FROM tf_traffic_stats);

在创建外键约束之前,您必须删除td_domain_name中无法与tf_traffic_stats匹配的条目,否则在{{1}中创建相应的条目}}

另外,从您的评论中可以看出,td_domain_name是一个静态域名列表。我将基于你的表名做出一个疯狂的猜测,你可能想要外键反过来,即。确保tf_traffic_stats中的tf_traffic_stats中的每个域都存在?

答案 2 :(得分:0)

您可以通过SHOW INNODB STATUS获取有关查询失败原因的详细信息。在输出中埋藏的是一个名为LAST FOREIGN KEY ERROR的部分,它将更详细地解释密钥失败的原因。

如果这两个表中都包含数据,则td_domain_name表中很可能有一个或多个值在tf_traffic_stats表中不存在,导致FK创建失败。如果您必须在不修复不匹配密钥的情况下创建FK,则可以使用set foreign_key_checks=0暂时禁用FK检查,然后执行alter语句。