在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
但是,记录的数量不应该匹配(即,左外连接不成功)。
欣赏它!
答案 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_name
中tf_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
语句。