如何在多对一关系上使用 DELETE ON CASCADE

发布于 2024-12-03 04:17:59 字数 263 浏览 1 评论 0原文

有人可以帮助我吗?我正在尝试一些东西,但我对(我的)SQL 太陌生了。

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

我希望表格类别保持整洁。因此,当 Items 中没有任何项目属于categories 中的类别 X 时,应从categories 中删除类别 X。你如何确定这一点。我猜测是通过使用 DELETE ON CASCADE 来实现的,但到目前为止,当我从类别中删除类别时,它只是从项目中删除相应的项目。

非常感谢您帮助我!

May someone help me out. I'm trying something, but I'm (too) new to (my)SQL.

I use two tables: Items and Categories. Table Items has a field with foreign key: category_id.

I want the table Categories to be kept tidy. So when no item in Items is of category X in Categories, the category X should be deleted from Categories. How do you establish that. I guessed by using DELETE ON CASCADE, but so far it was only deleting corresponding items from Items when I deleted a categorie from Categories.

Thanks a lot for helping me!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海拔太高太耀眼 2024-12-10 04:17:59

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

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

因此,您有项目,每个项目属于一个特定的类别。在您的项目表中,您有一个引用类别表中的行的category_id(请修正拼写)。因此,在您的情况下:

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

您所要求的有点相反:

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

无法使用 ON DELETE CASCADE 执行此操作,原因有两个:

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

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

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

ON DELETE CASCADE is a way of deleting a row when a row it references is deleted. This means:

  • You have a row in table A
  • You have a row in table B that references a row in table A
  • You delete the row in table A
  • The database deletes the corresponding row in table B

So you have items, and each item belongs to a particular category. In your items table, you have a category_id (and please fix your spelling) that refers to a row in the categories table. So, in your situation:

  • You have a category
  • You have an item that references a category
  • You delete a category
  • The database deletes all the items that correspond to that category

What you're asking for is sort of the other way around:

  • You have items
  • You delete the last item in a particular category
  • The database goes and finds that category and deletes it

There's no way to do this with ON DELETE CASCADE, for two reasons:

  1. How are you going to create an empty category before inserting your first item into it? The database would have to delete it immediately.
  2. The database would have to do a lot of extra work scanning the table. It doesn't "know" that item #23082 was the last item in the category; it would have to somehow be keeping track of the number of items in the category to do that.

This all stems from the fact that ON DELETE CASCADE is a way of maintaining referential integrity. That is, it's a way for the database to give you a strong guarantee that if you see category #20393 on item #9847, when you go look for category #20393 you know it exists. It is not a labor saving device. :) This is why the other options are ON DELETE SET NULL and ON DELETE RESTRICT: they also guarantee integrity, but instead of deleting, they remove the bad reference or prevent the original delete from occurring.

So the answer is, you will have to either write a cron job to periodically clean that table or use some kind of ON DELETE trigger, if you're worried about empty categories.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文