Quantcast
Channel: MySQL Forums - InnoDB
Viewing all articles
Browse latest Browse all 1954

Updating a column referenced by two foreign keys in the same table leads to foreign key constraint failure (1 reply)

$
0
0
I have a simple InnoDB table:

CREATE TABLE `T` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`deleted` bigint(20) unsigned NOT NULL DEFAULT '0',
`other` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`,`deleted`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

And another table that encodes relationships among entries from the first table:

CREATE TABLE `T_T` (
`id1` bigint(20) unsigned NOT NULL,
`deleted1` bigint(20) unsigned NOT NULL,
`id2` bigint(20) unsigned NOT NULL,
`deleted2` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id1`,`deleted1`,`id2`,`deleted2`),
KEY `fk_T_T_2_idx` (`id2`,`deleted2`),
CONSTRAINT `fk_T_T_2` FOREIGN KEY (`id2`, `deleted2`) REFERENCES `T` (`id`, `deleted`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_T_T_1` FOREIGN KEY (`id1`, `deleted1`) REFERENCES `T` (`id`, `deleted`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Creation of tables and population works perfectly fine.

INSERT INTO T (id, deleted, other) VALUES (1, 0, 'whatever');
INSERT INTO T_T (id1, deleted1, id2, deleted2) VALUES (1, 0, 1, 0);

Updating an entry in T, however, with something like this:

UPDATE T SET deleted = 1 WHERE id = 1;
leads to the following error:

ERROR 1452: 1452: Cannot add or update a child row: a foreign key constraint fails (`test`.`T_T`, CONSTRAINT `fk_T_T_1` FOREIGN KEY (`id1`, `deleted1`) REFERENCES `T` (`id`, `deleted`) ON DELETE CASCADE ON UPDATE CASCADE)

This works if the entries in T_T don't refer to self (id1 != id2). But an UPDATE will fail when a row in T_T refers with both ids to the same row in T.

Is there a problem in MySQL with foreign keys that refer to another table's column(s) twice? Is there a work around for something like this?

It almost appears that the foreign keys in T_T are updated separately. The sequence of internal MySQL operations appears to be: 1) update the record in T; b) cascade to the first foreign key in T_T; c) cascade to the second foreign key in T_T. But after step b) the second's foreign key constraints fail because it now points to a non-existent row in T. Does that make sense?

I can perform the update of T when foreign_key_checks is set to 0 for the duration of the UPDATE call. But then this prevents cascading of this update to other tables, which sort of defeats the purpose of cascading...

Viewing all articles
Browse latest Browse all 1954

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>