2012-10-19 215 views
12

这似乎是一个常见错误,但对于我的生活,我无法弄清楚这一点。MySQL - 无法添加或更新子行:外键约束失败

我在MySQL中有一组InnoDB用户表,它们通过外键连接在一起;父表user表和一组存储电子邮件地址,动作等的子表。这些都通过外键uid连接到父表user表,所有父键和子键都是int(10)

所有的子表都有一个uid值,其外键约束指向user.uid,并且设置为ON DELETE CASCADEON UPDATE CASCADE

当我从user中删除一个用户时,所有的子约束条目都被删除。然而,当我尝试更新user.uid值,它会导致下面的错误,而不是级联uid变化的子表:

#1452 - Cannot add or update a child row: a foreign key constraint fails (`accounts`.`user_email`, CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE) 

我有一种感觉,我必须在这里失去了一些东西明显。使用user_email删除密钥约束并尝试更新user中的值会导致相同的错误,但对于下一个字母表user子表,因此我不相信这是表特定的错误。

编辑:

在结果中添加从SHOW ENGINE INNODB STATUS

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
121018 22:35:41 Transaction: 
TRANSACTION 0 5564387, ACTIVE 0 sec, process no 1619, OS thread id 2957499248 updating or deleting, thread declared inside InnoDB 499 
mysql tables in use 1, locked 1 
17 lock struct(s), heap size 2496, 9 row lock(s), undo log entries 2 
MySQL thread id 3435659, query id 24068634 localhost root Updating 
UPDATE `accounts`.`user` SET `uid` = '1' WHERE `user`.`uid` = 306 
Foreign key constraint fails for table `accounts`.`user_email`: 
, 
    CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE 
Trying to add in child table, in index `uid` tuple: 
DATA TUPLE: 2 fields; 
... 
A bunch of hex code 

But in parent table `accounts`.`user`, in index `PRIMARY`, 
the closest match we can find is record: 
... 
A bunch of hex code 
+0

'SHOW ENGINE INNODB STATUS' –

+0

投票将其移至dba。 –

回答

1

在一个不相关的任务上,我最近提出了我们的MySQL数据库MySQL Workbench,当查看上表的关系时,我注意到'重复'和/或虚假关系,我以前不知何故错过了它们没有出现在PHPMyAdmin FWIW中)。消除这些额外的关系可以立即解决问题。

8

因为你没有给表定义,这是很难猜测。但它看起来像你试图修改子表中的外键。 AFAIK,这是非法的,你可以修改它从父,但不是子表。

考虑这个例子:

CREATE TABLE parent (
    parent_id INT NOT NULL, 
    parent_data int, 

    PRIMARY KEY (parent_id) 
) ENGINE=INNODB; 

CREATE TABLE child1 (
    child1_id INT, 
    child1_data INT, 
    fk_parent_id INT, 

    INDEX par_ind1 (fk_parent_id), 

    FOREIGN KEY (fk_parent_id) 
    REFERENCES parent(parent_id) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE 
) ENGINE=INNODB; 

CREATE TABLE child2 (
    child2_id INT, 
    child2_data INT, 
    fk_parent_id INT, 

    INDEX par_ind2 (fk_parent_id), 

    FOREIGN KEY (fk_parent_id) 
    REFERENCES parent(parent_id) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE 
) ENGINE=INNODB; 

INSERT INTO parent 
    (parent_id, parent_data) 
    VALUES 
    (1, 11), 
    (2, 12); 

INSERT INTO child1 
    (child1_id, child1_data, fk_parent_id) 
    VALUES 
    (101, 1001, 1), 
    (102, 1002, 1), 
    (103, 1003, 1), 
    (104, 1004, 2), 
    (105, 1005, 2); 

INSERT INTO child2 
    (child2_id, child2_data, fk_parent_id) 
    VALUES 
    (106, 1006, 1), 
    (107, 1007, 1), 
    (108, 1008, 1), 
    (109, 1009, 2), 
    (110, 1010, 2); 

那么这是允许的:

UPDATE parent 
    SET parent_id = 3 WHERE parent_id = 2; 

SELECT * FROM parent; 
SELECT * FROM child1; 
SELECT * FROM child2; 

但这不是,因为它从子表修改父FK:

UPDATE child1 
    SET fk_parent_id = 4 WHERE fk_parent_id = 1; 

它会得到与您的错误非常相似的错误:

Cannot add or update a child row: a foreign key constraint fails (`db_2_b43a7`.`child1`, CONSTRAINT `child1_ibfk_1` FOREIGN KEY (`fk_parent_id`) REFERENCES `parent` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE): 
+0

谢谢。我正在更新父表 - 查看我发布的转储中的查询:'UPDATE \'accounts \'。\'user''SET \'uid \'='1'WHERE \'user \'。\'uid \ '= 306'。 'user'是父表,并触发这个错误。 –

+0

你能发布更多关于你的模式的信息吗?或者修改上面的例子,以便得到相同的错误? – walrii

4

我在创建表上的外部约束时遇到了同样的问题。出现这个问题的简单方法是先备份父表和子表,然后截断子表并再次尝试创建关系。希望这会解决问题。

-1

希望这将有助于任何人在将CSV数据导入到相关表格时出现相同错误。在我的情况下,父表是确定的,但是在将数据导入包含外键的子表中时出现错误。在临时删除子表上的foregn键约束之后,我设法导入了这些数据,并惊讶地发现FK列中值为0的一些值(显然这是由于父表没有这些值在其PK栏中)。原因是,我的CSV列中的数据在FK列之前包含逗号(我用作字段分隔符)。更改我的CSV文件的分隔符解决了问题。

9

我解决了我加入以下代码,SQL代码的开始“外键约束失败”的问题(这是对进口值表)

SET @[email protected]@CHARACTER_SET_CLIENT; 
SET @[email protected]@CHARACTER_SET_RESULTS; 
SET @[email protected]@COLLATION_CONNECTION; 
SET NAMES utf8; 
SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; 
SET @[email protected]@SQL_NOTES, SQL_NOTES=0; 

然后将此代码添加到文件

SET [email protected]_SQL_MODE; 
SET [email protected]_FOREIGN_KEY_CHECKS; 
SET [email protected]_UNIQUE_CHECKS; 
SET [email protected]_CHARACTER_SET_CLIENT; 
SET [email protected]_CHARACTER_SET_RESULTS; 
SET [email protected]_COLLATION_CONNECTION; 
SET [email protected]_SQL_NOTES; 
+0

精美地工作 –

+0

它的工作原理!谢谢 – tiveor

+0

LIFE SAVER MAN,THANKS –

0

这样的更新的错误可能是由字符集和校对规则的不同而引起的末尾,以便确保它们是两个表的相同。

相关问题