当前位置:  开发笔记 > 数据库 > 正文

实现软删除的最佳方法是什么?

如何解决《实现软删除的最佳方法是什么?》经验,为你挑选了7个好方法。

目前正在处理项目,我们必须为大多数用户(用户角色)实施软删除.我们决定在数据库中的每个表上添加"is_deleted ='0'"字段,如果特定用户角色点击特定记录上的删除按钮,则将其设置为"1".

对于将来的维护,每个SELECT查询都需要确保它们不包含is_deleted ='1'的记录.

是否有更好的解决方案来实现软删除?

更新:我还应该注意到,我们有一个Audit数据库,用于跟踪Application数据库中所有表/字段的更改(字段,旧值,新值,时间,用户,ip).



1> ctcherry..:

我会倾向于使用deleted_at列的"Rails方式",该列包含删除发生的日期时间.然后,您将获得有关删除的一些免费元数据.对于SELECT,只需获取行WHERE deleted_at IS NULL


这就是我们这样做的方式 - 删除始终是一个日期字段
+1因为它与"最佳答案"中提供的解决方案具有完全相同的信息,并且附加地为您提供删除发生日期的信息.
@Corey绝对
我认为使用日期字段比使用标记更好,因为您可以通过多种方式对日期字段进行分区。

2> David J. Sok..:

您可以对包含该WHERE IS_DELETED='0'子句的视图执行所有查询.


不要忘记索引该列;)

3> Sergey Stadn..:

使用is_deleted列是一种相当不错的方法.如果是在Oracle中,为了进一步提高性能,我建议通过在is_deleted列上创建列表分区来对表进行分区.然后删除和未删除的行将物理上位于不同的分区中,但对于您来说它将是透明的.

因此,如果您键入一个类似的查询

SELECT * FROM table_name WHERE is_deleted = 1

然后Oracle将执行"分区修剪",只查看相应的分区.在内部,分区是一个不同的表,但作为用户,它对您来说是透明的:无论是否分区,您都可以在整个表中进行选择.但Oracle将只能查询它所需的相关性.例如,假设您有1000行IS_DELETED = 0和100000行,IS_DELETED = 1,并且您在IS_DELETED上对表进行分区.现在,如果你包括条件

WHERE ... AND IS_DELETED=0

那么Oracle将只扫描1000行的分区.如果表未分区,则必须扫描101000行(两个分区).



4> Jeremiah Pes..:

遗憾的是,最佳响应取决于您尝试使用软删除以及您正在实现此功能的数据库.

在SQL Server中,最好的解决方案是使用类型为SMALLDATETIME或DATETIME的deleted_on/deleted_at列(取决于必要的粒度)并使该列可以为空.在SQL Server中,行标题数据包含表中每个列的NULL位掩码,因此执行IS NULL或IS NOT NULL比检查存储在列中的值要快一些.

如果您有大量数据,则需要通过数据库本身或通过两个单独的表(例如Products和ProductHistory)或通过索引视图来查看数据分区.

我通常会避免像is_deleted,is_archive等标志字段,因为它们只带有一个含义.可以为null的deleted_at,archived_at字段为您自己和继承您的应用程序的人提供了额外的意义.我避免像瘟疫这样的位掩码字段,因为它们需要了解如何构建位掩码以便掌握任何含义.


我同意,"deleted_at"比简单的"is_deleted"更为可取,因为你可以免费获得额外的信息.

5> Jiaaro..:

如果表很大并且性能有问题,您可以随时将"已删除"记录移动到另一个表,其中包含删除时间,删除记录等其他信息.

这样您就不必在主表中添加其他列


我实际上真的很喜欢这个主意,因为那时我的主表没有成千上万条软删除的记录。但是,您将如何处理子记录和相关记录?您是否会基本上重新创建相同的表依赖关系(例如订单和订单商品)?

6> Daniel Fortu..:

这取决于您需要哪些信息以及您希望支持哪些工作流程.

你想要能够:

知道那里有什么信息(在删除之前)?

知道什么时候被删除了?

知道谁删了它?

知道他们删除它时的行为能力是什么?

能够取消删除记录吗?

能够告诉它何时被删除?

等等

如果记录被删除和未删除四次,是否足以让您知道它当前处于未删除状态,或者您是否希望能够告知过渡期间发生的事情(包括连续之间的任何编辑)删除!)?



7> 小智..:

小心软删除的记录导致违反唯一性约束.如果您的数据库具有唯一约束的列,请注意先前的软删除记录不会阻止您重新创建记录.

想想周期:

    创建用户(login = JOE)

    soft-delete(将已删除列设置为非null.)

    (重新)创建用户(login = JOE).错误.已登录LOGIN = JOE

第二次创建导致约束违规,因为login = JOE已经在软删除行中.

一些技巧:1.将删除的记录移动到新表.2.在login和deleted_at timestamp列中创建唯一性约束

我自己的意见是+1移动到新表.它需要很多纪律来维护所有查询中的*AND delete_at = NULL*(适用于所有开发人员)


嗨,安迪,我恰好遇到了您的情况。但是我认为转移到另一张桌子并不能长期维护。选项2似乎更好。.为什么不推荐呢?我只是好奇。
推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有