问题标签 [soft-delete]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
1998 浏览

sql - 实现对性能和代码影响最小的软删除

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

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

  • 添加一个is_deleted布尔字段。

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

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

对于以上两者

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

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

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

有更好的选择吗?

0 投票
2 回答
626 浏览

mysql - 软删除用户表?或者还有其他选择吗?

阅读了所有关于软删除的赞成与反对的文章,我的头脑在旋转。但这是我知道实现这一目标的唯一方法:

维护外键和用户信息(历史数据)即使用户被删除/不活动,评论、附件和故事表中也有外键。这样仍然可以确定是他写了这篇评论等。

其他信息:

停用的用户无法登录,不会包含在列表中。

但是,如果我使用软删除,那么每次查询该表时,在 sql 语句中的 WHERE 中添加一个额外的列并不是很好。

该怎么办?希望各位大佬可以给点意见。

注意:我使用mysql和ROR

0 投票
2 回答
1039 浏览

c# - 从 DbContext Set() 中过滤掉软删除

如何过滤IsSoftDeleted掉这个 DbSet 中的项目?

方法

模型

编辑:忘记显示Whatever源自BaseEntity

0 投票
2 回答
3413 浏览

indexing - 软删除 - 使用 IsDeleted 标志或单独的连接表?

我们应该为软删除使用标志,还是使用单独的连接器表?哪个更有效率?数据库是 SQL Server。

背景资料

不久前,我们有一位数据库顾问进来查看我们的数据库模式。当我们软删除一条记录时,我们将更新相应表上的 IsDeleted 标志。建议不要使用标志,将删除的记录存储在单独的表中并使用连接,因为这样会更好。我已经对这个建议进行了测试,但至少从表面上看,额外的表和连接看起来比使用标志更昂贵。

初步测试

我已经设置了这个测试。

两个表,Example 和 DeletedExample。我在 IsDeleted 列上添加了一个非聚集索引。

我做了三个测试,加载了一百万条具有以下已删除/未删除比率的记录:

  • 已删除/未删除
  • 50/50
  • 10/90
  • 1/99

结果 - 50/50 50 50

结果 - 10/90 10 90

结果 - 1/99 在此处输入图像描述

数据库脚本,供参考、示例、DeletedExample 和 Example.IsDeleted 的索引

0 投票
1 回答
4007 浏览

php - Doctrine2 + 软删除作为状态模式

Doctrine2 文档说软删除行为应该更好地实现为状态模式,但没有提供该实现的任何示例。

如何使用状态模式实现软删除行为?

0 投票
3 回答
3079 浏览

entity-framework - 实体框架代码优先软删除延迟加载

所以我首先使用实体​​框架代码(所以没有.edmx)我有一个带有布尔 IsEnabled 的基实体类来执行软删除

我正在使用存储库模式,因此可以使用 IsEnabled 过滤掉所有针对存储库的查询。

但是,任何时候我使用存储库获取 IsEnabled 的 MyType,延迟加载 MyType.Items 可能意味着无法启用项目。

有没有办法,也许用 EF Fluent 来描述如何对表进行过滤?

更新:

如果我有一个数据库集

有什么办法可以告诉 DbContext 过滤 DbSet?

0 投票
1 回答
3825 浏览

relational-database - 软删除与数据库存档

推荐阅读

  • 类似:软删除是个好主意吗?
  • 好文章:http ://weblogs.asp.net/fbouma/archive/2009/02/19/soft-deletes-are-bad-m-kay.aspx

    我是怎么来到这里的

    我坚信,在制作软件时,任何预先做的以尽量减少以后的工作都会在卡车负载中得到回报。因此,我试图确保在处理我的数据库架构和维护时,它可以保持关系完整性,同时不会过时或过于复杂。

    当看到典型的删除方法 CASCADE 时,这导致了一种不寒而栗。哎呀,我目前的情况有点过头了。我想保持关系图的完整性,但我不想仅仅因为链的一部分不相关而删除每个图。因此,我选择了软删除的方式,以确保数据的完整性保持不变,而记录可以从相关性中删除。我通过向数据库中的每个sigh表添加一个“DateDeleted”字段来实现这一点。

    转折点

    然而,这显然开始增加太多的复杂性和工作是值得的。我在不应该去的地方加入了逻辑,并且不想在我的整个应用程序中延续这些不良做法。简而言之,我将回滚这个实现。

    在查找天气时人们喜欢软删除,似乎有很多支持它。事实上,链接的“类似”帖子顶部显示了“我总是软删除”的最高投票答案。此外,那里和周围的大多数答案都包括某种“isDeleted”或“isActive”类型的方法。

    新的实施理念

    链接的“好文章”涵盖了我实际开始遇到的一些问题。它还提出了一种软删除的替代方法,我从最佳实践的角度发现了这种方法。建议是使用“存档数据库”,我在查看软删除时实际上已经考虑过。我决定反对它的原因是因为我之前提到的关于 CASCADE 删除的观点。我很谨慎地从数据库中删除整个图表,因为链的一部分被删除了。但是,这个图表至少可以从档案中保留下来,所以我不确定它是否真的那么糟糕。

    十字路口

    那么,我应该继续添加逻辑,逻辑,逻辑......逻辑吗?或者,我是否应该考虑将大部分逻辑放在一个非常复杂的图形管理类中来存储/恢复关系对象图的存档数据库?后者对我来说似乎是最佳实践。

  • 0 投票
    2 回答
    2757 浏览

    ruby-on-rails - Rails - 活动和非活动数据的软删除或存档

    我已经阅读了很多关于软删除和存档的内容,并且看到了所有的优点和缺点。我仍然对哪种方法最适合我的情况感到困惑。我将使用帖子和评论的概念,看看我是否可以更容易地解释它

    帖子被“删除”,但我需要仍然可以从 RSS 提要访问帖子,但不是应用程序的管理员。

    我听到很多关于软删除的头痛,但认为这对我的应用程序可能最有意义,并且觉得如果我使用存档,那么我将不得不运行多个查询

    不确定@$$ 中哪个更有效或更痛苦。想法或例子?我知道这个例子听起来很愚蠢,但试图想出多种情况可以用来找出走哪条路。

    0 投票
    1 回答
    279 浏览

    database-design - 关于级联恢复的软删除通用属性

    软删除一般用什么类型的字段?这些中的任何一个,还有其他的吗?

    我问的原因是,在使用软删除时,仍必须实施级联以保持完整性。然而,真正的诀窍不是级联删除,这很容易。

    The trick is cascade restoring. 在级联删除中,使用软删除方案,关系图中的所有记录都被标记为已删除、非活动,无论标志是什么,也许不同之处在于将 datedeleted 更改为 null 值。在级联恢复时,必须评估记录引用以查看它们被删除的原因是否是与正在恢复、重新激活、取消删除的记录相关的级联删除的结果。

    如何处理存储数据的级联恢复操作?

    0 投票
    1 回答
    279 浏览

    sql - 通过软删除保持逻辑一致性,同时保留原始信息

    我有一个非常简单的表students,结构如下,主键在哪里id。该表是大约 20 个数百万行的表的替身,这些表经常连接在一起。

    如果 Bob 想更改他的出生日期,那么我有几个选择:

    1. 更新students新的出生日期。

      积极因素: 1 DML 操作;该表始终可以通过单个主键查找来访问。

      负面因素:我失去了 Bob 曾认为他出生于 1990 年 4 月 6 日这一事实

    2. 在表中添加一列 ,created date default sysdate并将主键更改为id, created。每一个都update变成:

      然后,每当我想要最新信息时,请执行以下操作(Oracle 但问题代表每个 RDBMS):

      优点:我从不丢失任何信息。

      负面因素:对整个数据库的所有查询都需要更长的时间。如果表格是指示的大小,这无关紧要,但是一旦您在第 5 次left outer join使用范围扫描而不是唯一扫描,就会开始产生影响。

    3. 添加一个不同的专栏,deleted date default to_date('2100/01/01','yyyy/mm/dd')或任何我喜欢的过早或未来主义的日期。将主键更改为id, deleted然后每个update变为:

      获取当前信息的查询变为:

      优点:我从不丢失任何信息。

      否定:两个 DML 操作;我仍然必须使用额外成本的排名查询或范围扫描,而不是每个查询中的唯一索引扫描。

    4. 创建第二个表,说student_archive并将每个更新更改为:

      优点:永远不要丢失任何信息。

      否定: 2个DML操作;如果您想获得您必须使用的所有信息union或额外的left outer join.

    5. 为了完整起见,有一个可怕的去规范化的数据结构:id, name1, dob, name2, dob2...等等。

    如果我不想丢失任何信息并总是进行软删除,那么第 1 号不是一个选项。5 号可以安全地丢弃,因为它造成的麻烦多于它的价值。

    我只剩下选项 2、3 和 4 以及随之而来的负面影响。我通常最终使用选项 2 和可怕的 150 行(间隔很好)多个子选择连接。


    tl;博士我意识到我在这里的“非建设性”投票中滑到了接近线的位置,但是:

    在不删除任何数据的同时保持逻辑一致性的最佳(单一!)方法是什么?

    有没有比我记录的更有效的方法?在这种情况下,我将高效定义为“更少的 DML 操作”和/或“能够删除子查询”。如果您在(如果)回答时能想到更好的定义,请随意。