如何处理从某个表中删除许多对象

时间:2010-01-19 04:28:32

标签: mysql database-design foreign-keys

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

在这种情况下处理删除的最佳做法是什么,如果UI没有显示复选框,如果可能有其他依赖于此用户的记录,这实际上意味着在呈现此用户列表页面时您需要执行其他操作每行检查以确定是否需要启用该复选框

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

1 个答案:

答案 0 :(得分: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列的索引,而不必读取行数据。