【问题标题】:How to use DELETE ON CASCADE on many-to-one relation如何在多对一关系上使用 DELETE ON CASCADE
【发布时间】:2011-11-09 15:27:30
【问题描述】:

请有人帮帮我。我正在尝试一些东西,但我对(我的)SQL (太)陌生。

我使用两个表:项目和类别。表项有一个外键字段:category_id。

我希望表格类别保持整洁。因此,当 Items 中没有商品属于 Categories 中的类别 X 时,应从类别中删除类别 X。你如何确定这一点。我猜测是在 CASCADE 上使用 DELETE,但到目前为止,当我从 Categories 中删除一个类别时,它只是从 Items 中删除相应的项目。

非常感谢您帮助我!

【问题讨论】:

    标签: mysql sql cascading-deletes


    【解决方案1】:

    ON DELETE CASCADE 是一种在删除它引用的行时删除行的方法。这意味着:

    • 表 A 中有一行
    • 表 B 中有一行引用了表 A 中的一行
    • 您删除了表 A 中的行
    • 数据库删除表B中的对应行

    所以你有项目,每个项目都属于一个特定的类别。在您的 items 表中,您有一个 category_id(请修正您的拼写),它指的是 categories 表中的一行。所以,在你的情况下:

    • 您有一个类别
    • 您有一个引用类别的项目
    • 您删除了一个类别
    • 数据库删除与该类别对应的所有项目

    你要求的是另一种方式:

    • 你有物品
    • 您删除了特定类别中的最后一项
    • 数据库找到该类别并将其删除

    ON DELETE CASCADE 无法做到这一点,原因有两个:

    1. 在向其中插入第一个项目之前,您将如何创建一个空类别?数据库必须立即删除它。
    2. 数据库将不得不做很多额外的工作来扫描表。它不“知道”项目#23082 是该类别中的最后一项;它必须以某种方式跟踪类别中的项目数量才能做到这一点。

    这一切都源于ON DELETE CASCADE 是一种维护参照完整性的方式。也就是说,这是数据库向您提供强有力保证的一种方式,即如果您在项目 #9847 上看到类别 #20393,当您查找类别 #20393 时您知道它存在。它不是省力设备。 :) 这就是为什么其他选项是 ON DELETE SET NULLON DELETE RESTRICT 的原因:它们也保证完整性,但不是删除,而是删除错误引用或防止发生原始删除。

    所以答案是,如果您担心空类别,您将不得不编写一个 cron 作业来定期清理该表或使用某种 ON DELETE 触发器。

    【讨论】:

    • 如果可以的话,我会给 +10。这么好的答案。
    • 很好的解释。非常感谢!
    • 如果您认为这是一个很好的解释,如果您接受这个答案,那就太好了。
    • 我不知道为什么我之前没有接受答案。我可能没有被允许这样做。从今天开始,我可以将答案标记为“有用”:-)
    • @Barthelomeus 谢谢,这是我有史以来最成功的一次。 :)
    猜你喜欢
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 2016-09-28
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多