如何使用 ON DELETE 仅删除孤立子行?

问题描述 投票:0回答:1

我有一个父表和一个子表。父行存储子行的外键。如果我将外键的约束设置为 ON DELETE CASCADE,那么当我想要删除父行(其中外键指向其他父行正在使用的子行)时,就会抛出错误。

此 SQL 查询列出了子行以及它们出现的次数。父行是人,子行是国家。

SELECT country_id, country, COUNT(person.id) FROM nobel_prizes.person JOIN nobel_prizes.countries c on c.id = person.country_id GROUP BY country_id;

使用此结果,我可以轻松删除孤立行。但有没有更合适的方法来做到这一点?

sql mysql database database-design
1个回答
0
投票

我认为你有几个概念颠倒了。

习惯上将带有外键的表称为子表。外键引用的表称为父表。在您的情况下,

person
表是
countries
表的子项,而不是相反。

如果您使用

person
选项在
ON DELETE CASCADE
中定义外键,则从
countries
中删除父行会导致删除
person
中引用已删除行的所有子行也被删除。

孤行是没有父行的行。这违反了引用完整性。

不存在声明性引用完整性(又名外键)支持的反向级联操作。也就是说,如果您删除给定国家/地区的

person
中的最后一行,则不会删除该国家/地区。
countries
中的行有零个子行依赖于它,这并不违反引用完整性。那不是孤儿,只是一个还没有孩子的父母。
如果您想手动查找引用它的人数为零的国家/地区,请使用如下查询:

person

在这种情况下,您需要使用外连接,因为内连接只会匹配 
SELECT country_id, country, COUNT(person.id) FROM nobel_prizes.person LEFT OUTER JOIN nobel_prizes.countries c on c.id = person.country_id GROUP BY country_id HAVING COUNT(person.id) = 0;

中那些在

countries
中具有一个或多个匹配行的行。要查找无子项的国家/地区,您特别需要
person
中子行为零的国家/地区。
我不认为需要从 

person

中删除行。目前地球上只有 195 个国家。

    

© www.soinside.com 2019 - 2024. All rights reserved.