2013-10-23 18 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命令;它應該成功。

相關問題