3

关于这个话题有一些类似的 问题,但它们并没有真正帮助我。

我想在 StackOverflow 上实现一个软删除功能,其中项目并没有真正删除,而只是隐藏了。我正在使用 SQL 数据库。这里有 3 个选项:

  • 添加一个is_deleted布尔字段。

    • 优点:简单。
    • 缺点:没有日期记录。强制我is_deleted = 0在每个查询中添加一个。
  • 添加deleted_date日期字段。NULL如果未删除,则设置为。

    • 优点:有日期。
    • 缺点:仍然使我的查询混乱。

对于以上两者

  • 它也会影响性能,因为有所有这些无用的行。它们仍然必须在索引中维护。此外,在获取未删除(大多数)行时,列上的索引deleted也无济于事。需要全表扫描。

另一种选择是创建一个单独的表来保存已删除的项目:

  • 优点:在查询未删除的行时提高了性能。无需为我对未删除行的查询添加条件。索引维护更容易。
  • 缺点: 复杂性:删除和取消删除都需要数据迁移。需要新表。参照完整性更难处理。

有更好的选择吗?

4

5 回答 5

3

我个人会根据您预计用户希望访问已删除数据或“恢复”已删除数据的频率来回答我的问题。

如果经常发生,那么我会使用“Date_Deleted”字段并将计算出的“IsDeleted”放在我的代码中的 poco 中。

如果它从不(或几乎从不),那么历史表或已删除表对您解释的好处有好处。

我个人几乎从不使用已删除的表(并选择 isDeleted 或 date_deleted),因为存在引用完整性的潜在风险。您有 A -> B 并且您从 B 数据库中删除了记录...由于您的设计选择,您现在必须管理参考完整性。

于 2011-09-09T20:08:02.467 回答
2

在我看来,当考虑缩放和最终的表/数据库大小时,最好的前进方式是您的第三个选择 - 为已删除项目创建一个单独的表。这样的表最终可以移动到不同的数据库以支持扩展。

我相信您已经列出了三个最常见的选项。如您所见,每个都有优点和缺点。就个人而言,我喜欢从长远角度看待事物。

于 2011-09-09T20:06:40.227 回答
2

如果键是数字,我通过否定键来处理“软删除”。(当然,不适用于身份密钥)。您根本不需要更改代码,并且可以通过乘以 -1 轻松恢复记录。

只是另一种考虑的方法......如果键是字母数字,您可以通过添加一个独特的“标记”字符来做类似的事情。由于已删除的记录都以该标记开头,因此将在索引中自行结束。

于 2011-09-09T20:14:03.753 回答
2

我认为您对选项的分析很好,但您错过了我在下面列出的一些相关点。正如您在前两个选项中建议的那样,几乎所有我见过的实现都在行上使用某种已删除或版本控制字段。

使用带有已删除标志的表: 如果您的索引都首先包含已删除标志字段,并且您的查询主要包含 where isdeleted=false 类型结构,那么它确实解决了您的性能问题,并且索引非常有效地排除了已删除的行。类似的逻辑可以用于删除日期选项。

使用两个表格 通常,您需要对报告进行大量更改,因为某些报告可能引用已删除的数据(例如旧的销售数据可能引用已删除的销售类别)。可以通过创建一个视图来克服这个问题,该视图是要读取和仅写入活动记录表的两个表的联合。

于 2016-05-16T12:25:32.597 回答
1

假设我们创建了一个名为dead标记已删除行的字段。我们可以创建一个字段dead为 false 的索引。这样,我们只使用提示使用索引搜索未删除的行。

于 2016-05-16T12:05:43.190 回答