MySQL - 删除级联约束没有正确完成它的工作
MySQL - On delete cascade constraint doesn't do it's job properly
我有几个 table:
users
已满用户。
item
已装满物品。
item
可以有多个 second_item
。
users
可以通过 table users_items
. 得到 second_item
当我删除 item
时,所有 second_item
和 users_items
也应该被删除。所以我设置了一些应该删除子 table 记录的约束。但是它在 users_items
.
中留下了记录
这是我的 MySQL 查询:
CREATE TABLE `item` (
`id` int(10) UNSIGNED NOT NULL,
`name` varchar(63) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `item` (`id`, `name`) VALUES (1, 'test');
CREATE TABLE `second_item` (
`id` int(10) UNSIGNED NOT NULL,
`item_id` int(10) UNSIGNED DEFAULT NULL,
`name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `second_item` (`id`, `item_id`, `name`) VALUES
(1, 1, 'test');
CREATE TABLE `users` (
`id` int(10) UNSIGNED NOT NULL,
`email` varchar(200) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users` (`id`, `email`, `password`) VALUES (1, 'test', 'test');
CREATE TABLE `users_items` (
`id` int(10) UNSIGNED NOT NULL,
`user_id` int(10) UNSIGNED DEFAULT NULL,
`item_id` int(10) UNSIGNED DEFAULT NULL,
`item_second_id` int(10) UNSIGNED DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users_items` (`id`, `user_id`, `item_id`, `item_second_id`) VALUES (1, 1, 1, 1);
ALTER TABLE `second_item`
ADD PRIMARY KEY (`id`),
ADD KEY `item_id` (`item_id`);
ALTER TABLE `item` ADD PRIMARY KEY (`id`);
ALTER TABLE `users` ADD PRIMARY KEY (`id`);
ALTER TABLE `users_items`
ADD PRIMARY KEY (`id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `item_id` (`item_id`),
ADD KEY `item_second_id` (`item_second_id`);
ALTER TABLE `second_item`
ADD CONSTRAINT `constraint1` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `users_items`
ADD CONSTRAINT `constraint2` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `constraint3` FOREIGN KEY (`item_second_id`) REFERENCES `second_item` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `constraint4` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
我尝试执行以下删除查询,但它在 users_items
中留下了一条记录:
DELETE FROM `item` WHERE `item`.`id` = 1;
这 "bug" 发生在:
- WAMP(服务器版本:5.7.16 - MySQL 社区服务器 (GPL))
- UBUNTU (5.7.20-0ubuntu0.16.04.1 - (Ubuntu))
已编辑:
错误是由您添加约束的顺序引起的:
ALTER TABLE `users_items`
ADD CONSTRAINT `constraint1` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `constraint2` FOREIGN KEY (`item_second_id`) REFERENCES `second_item` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `constraint3` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `second_item`
ADD CONSTRAINT `constraint4` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
这样就固定了。
我确实得到了和你一样的结果。
还找到了修复 ;)
更改 SQL 代码中约束的顺序。这将解决您的问题。
我认为这是一个奇怪的 MySQL 错误
我有几个 table:
users
已满用户。item
已装满物品。item
可以有多个second_item
。users
可以通过 tableusers_items
. 得到
second_item
当我删除 item
时,所有 second_item
和 users_items
也应该被删除。所以我设置了一些应该删除子 table 记录的约束。但是它在 users_items
.
这是我的 MySQL 查询:
CREATE TABLE `item` (
`id` int(10) UNSIGNED NOT NULL,
`name` varchar(63) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `item` (`id`, `name`) VALUES (1, 'test');
CREATE TABLE `second_item` (
`id` int(10) UNSIGNED NOT NULL,
`item_id` int(10) UNSIGNED DEFAULT NULL,
`name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `second_item` (`id`, `item_id`, `name`) VALUES
(1, 1, 'test');
CREATE TABLE `users` (
`id` int(10) UNSIGNED NOT NULL,
`email` varchar(200) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users` (`id`, `email`, `password`) VALUES (1, 'test', 'test');
CREATE TABLE `users_items` (
`id` int(10) UNSIGNED NOT NULL,
`user_id` int(10) UNSIGNED DEFAULT NULL,
`item_id` int(10) UNSIGNED DEFAULT NULL,
`item_second_id` int(10) UNSIGNED DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users_items` (`id`, `user_id`, `item_id`, `item_second_id`) VALUES (1, 1, 1, 1);
ALTER TABLE `second_item`
ADD PRIMARY KEY (`id`),
ADD KEY `item_id` (`item_id`);
ALTER TABLE `item` ADD PRIMARY KEY (`id`);
ALTER TABLE `users` ADD PRIMARY KEY (`id`);
ALTER TABLE `users_items`
ADD PRIMARY KEY (`id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `item_id` (`item_id`),
ADD KEY `item_second_id` (`item_second_id`);
ALTER TABLE `second_item`
ADD CONSTRAINT `constraint1` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `users_items`
ADD CONSTRAINT `constraint2` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `constraint3` FOREIGN KEY (`item_second_id`) REFERENCES `second_item` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `constraint4` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
我尝试执行以下删除查询,但它在 users_items
中留下了一条记录:
DELETE FROM `item` WHERE `item`.`id` = 1;
这 "bug" 发生在:
- WAMP(服务器版本:5.7.16 - MySQL 社区服务器 (GPL))
- UBUNTU (5.7.20-0ubuntu0.16.04.1 - (Ubuntu))
已编辑:
错误是由您添加约束的顺序引起的:
ALTER TABLE `users_items`
ADD CONSTRAINT `constraint1` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `constraint2` FOREIGN KEY (`item_second_id`) REFERENCES `second_item` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `constraint3` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `second_item`
ADD CONSTRAINT `constraint4` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
这样就固定了。
我确实得到了和你一样的结果。 还找到了修复 ;)
更改 SQL 代码中约束的顺序。这将解决您的问题。
我认为这是一个奇怪的 MySQL 错误