2013-10-23 19 views
2

我有这两个表和一些数据已经在他们。有没有办法在表中已经有一些数据的情况下添加一个外键?

CREATE TABLE `system_user_data` (
`id_user` bigint(20) NOT NULL AUTO_INCREMENT, 
`user_login` varchar(15) DEFAULT NULL, 
PRIMARY KEY (`id_user`) 
) ENGINE=InnoDB AUTO_INCREMENT=120 DEFAULT CHARSET=utf8; 

CREATE TABLE `system_user_tokens` (
`id_token` bigint(20) NOT NULL AUTO_INCREMENT, 
`token_user` bigint(20) DEFAULT NULL, 
`token_token` varchar(20) DEFAULT NULL, 
`token_createdate` date DEFAULT NULL, 
    PRIMARY KEY (`id_token`) 
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; 

当我尝试添加外键token_user = id_user时出现错误。当没有任何数据时它正在工作。

alter table system_user_tokens add foreign key (token_user) references system_user_data (id_user); 

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`name`.`#sql-1b44_727`, CONSTRAINT `#sql-1b44_727_ibfk_1` FOREIGN KEY (`token_user`) REFERENCES `system_user_data` (`id_user`)) 
+0

外键旨在强制数据中的父子关系。如果你有悬挂的记录,那么你应该不使用外键,直到你修复了断开的关系。这样做基本上违背了外键的用途。 “我有一个苹果,有没有办法让它不是苹果?” –

+0

您可以添加一个有效的默认值,然后根据需要进行更新。不完全是一个好方法。 –

+0

这就是说,你* CAN *暂时禁用FK强制执行,但通常只在某些特殊情况下使用(例如加载转储/备份文件)。在正常使用情况下,禁用它们并不是一个好主意。请参阅http://stackoverflow.com/questions/15501673/how-to-temporarily-disable-a-foreign-key-constraint-in-mysql –

回答

4

是的,可以添加一个外键约束,是的,你做的是对的。

问题是,为了添加外键约束成功,表中的数据必须已经符合该约束,即system_user_tokens.token_user值的所有行必须存在于system_user_data.id_user中。目前,对于system_user_tokens表中的一行或多行,这不是真的。

运行此查询找到所有违规的外键,您尝试添加:

SELECT * 
FROM system_user_tokens tok 
WHERE NOT EXISTS (
    SELECT * FROM system_user_data u WHERE tok.token_user = u.id_user 
) 

分析由该查询返回的行,修复所有违规行为,并再次运行alter命令;它应该成功。

相关问题