关系数据库 - 要删除还是不删除?

时间:2013-12-15 14:32:54

标签: java mysql sql database crud

我刚从一位同事那里听说删除关系数据库中的行非常危险(关于索引和级联操作)

他说,允许删除的一个解决方案是为每个实体设置一个“已弃用”字段,而是将该字段设置为true,以便将该行标记为“已删除”。

当然,这将要求您在所有查询中获取所有“专用”== false(这非常麻烦)

我的问题是:

  1. 他是对的吗?如果是这样 - 完全删除究竟有什么危险?
  2. 他的解决方案是一个好习惯吗?
  3. 此解决方案的任何替代方案都可用吗?
  4. 感谢。

3 个答案:

答案 0 :(得分:1)

危险?服务器或数据中心是否会爆炸?

我认为你的同事沉迷于一些夸张。

如果您不希望,则无需级联更新或删除,但它比手动清理更容易。这是您在创建架构时所做的选择。

使用标记将行标记为已删除是另一种方法,但它只是另一种选择。你必须更加努力地找到所有坏行并运行批处理作业来删除它们。

如果您有保留要求,则更常见的是对模式进行分区并将旧记录移入仓库以进行历史分析和报告。在这种情况下,你不会删除任何东西,只是在一段时间后将它们移出。

答案 1 :(得分:1)

  1. 是的,他是对的。数据库(特别是索引)针对插入和删除进行了优化,可能会非常缓慢。即使将索引字段设置为null也会导致同样的问题。我认为级联是一个较小的问题,因为db永远不应该被配置为自动执行危险的级联。

  2. 是的,将记录标记为“非活动”,“已删除”,“已弃用”(您的选择)是解决与删除相关的性能问题的标准和首选做法。

    但是,为了限定上述内容,它仅适用于事务性(而不是 archival )表,然后仅适用于包含大量表的那些特定表。行(数百万甚至更多)。不要全心全意地采用“最佳实践”。

  3. 另一种方法是简单地没有包含数百万行的事务表。在数据增长到这样的比例之前,将数据移动到档案表。

答案 2 :(得分:1)

这个问题有多个层次。一般来说,最好将行标记为已删除而不是实际删除它们。

有一些主要的好处:

  1. 数据可以恢复。您可以向用户提供取消删除。
  2. 更新比删除更快。
  3. 在面向公众的应用程序中,没有一个可公开交互的代码具有真正的删除功能,因此使用该代码更加困难(sql注入等)
  4. 如果您想报告数据,可以。
  5. 当然有警告和最佳做法:

    1. 这不适用于易于重新创建数据的查找表。
    2. 您需要考虑剔除。在我们的数据库中,我们将删除的记录剔除到档案报告表中。这样可以使主表保持快速,但允许我们报告与“已删除”项目相关的数据。
    3. 您的淘汰性能影响(大规模)将类似于备份并具有类似的考虑因素。如果你想一次性存档它们,可以在几个小时内运行它们,如果你想每小时拿一个X数字,可以定期通过cron运行它们。
    4. 从不在您的实时数据中使用已删除的数据。换句话说,它不是状态标志!它已经消失了。我之前犯了这个错误,撤消它很痛苦。
    5. 如果表中删除的百分比很高,请问自己保留数据是否真的很重要。您可以将剔除过程调整为不归档,而只是运行实际删除。
    6. 这种方法将持续相当长的时间,除非您的数据集很大并且删除量很大。一些建筑宇航员会问你在归档10亿行时会发生什么......当你到达那一点时,你要么非常成功又能找到另一种方式,或者你已经完全搞砸了其他东西了存档任务与您遇到的其他问题无关。