【问题标题】:how to handle deletion of many objects from a certain table如何处理从某个表中删除许多对象
【发布时间】:2010-01-19 04:28:31
【问题描述】:

我们有一个包含公司所有用户的用户表。作为管理员,您有权删除用户条目。 UI 显示所有用户,每行带有一个复选框,以指示是否需要将其删除。其他表很可能与用户表有外键关系,因此会通过抛出外键约束违规来防止删除。

在这种情况下处理删除的最佳做法是什么检查每行以确定是否需要启用复选框

在这种情况下,最佳做法是什么。

【问题讨论】:

  • 理论上应该有级联删除的机制(FK关系的好处),你用的是什么数据库软件?

标签: mysql database-design foreign-keys


【解决方案1】:

首先,如果您被允许DELETE 用户记录,我会感到惊讶。您更有可能将它们标记为锁定或不允许登录或其他内容。有时,出于历史目的保留数据很重要。

其次,如果您确实需要删除行(在这种情况或其他情况下),您应该阅读有关使用 ON DELETE CASCADE 或其他选项的外键。

http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

当你删除父行(用户)时,你可以在依赖表的外键约束中声明你想要的行为:

  • RESTRICT,意思是如果有依赖行就不要删除父行
  • CASCADE,意思是自动、原子地删除所有依赖行
  • SET NULL,表示将子表中外键列的值改为NULL
  • SET DEFAULT,表示将外键列中的值更改为为该列定义的默认值

当然,这些约束只在 InnoDB 中有效。 MyISAM 不支持外键。


关于您的评论:不,没有办法快速检查是否存在引用给定用户行的相关行。这些统计数据必须在逐个用户的基础上进行管理。因此它将包含有关复制相关行本身的顺序的数据。此时,您不妨直接查询数据,而不是假设的统计数据。以下是我的做法:

SELECT u.*
FROM Users u
LEFT OUTER JOIN SomeChildTable1 c1 ON (u.user_id = c1.user_id)
LEFT OUTER JOIN SomeChildTable2 c2 ON (u.user_id = c2.user_id)
...other tables
WHERE c1.user_id IS NULL AND c2.user_id IS NULL AND ...other terms

通过外连接,c1、c2等中的列在没有匹配时为NULL,Users中的列无论是否匹配都返回。所以查询只返回那些没有依赖行的Users

有些人回避联接,因为他们在一些杂志文章中被告知联接成本很高,但与完成您想要的其他解决方案相比,联接看起来并没有那么糟糕。在这种情况下,它可以利用这些外键中user_id 列上的索引,而根本不必读取行数据。

【讨论】:

  • 是的,为历史数据保留某些用户记录非常重要。我想要删除出于测试等目的而错误创建的用户记录的选项。根据您的建议,我想使用 RESTRICT 选项是有意义的,这样在存在子行的情况下不会删除父行。但我宁愿不显示具有依赖行的条目的复选框选项,在这种情况下,是否可以说“我必须在构造此列表时查询每一行的依赖关系并适当地禁用它们”跨度>
  • 棘手的部分是,如果用户条目依赖于许多表以确定是否可以删除用户条目,您可能需要快速检查所有这些依赖表以获取引用将是一个耗时的选择。有没有更好的方法来快速检查是否存在依赖关系?
猜你喜欢
  • 2015-07-27
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
相关资源
最近更新 更多