软删除一个好主意?

软删除一个好主意或坏主意?

而不是实际删除数据库中的logging,只需将其标记为IsDeleted = true ,并在恢复logging时,可以将其标记为False

这是一个好主意吗?

将物理删除logging,然后将其移动到归档数据库是更好的办法,如果用户想要logging,那么软件会查找归档中的logging并重新创buildlogging?

我通常说这是一个坏主意(也许有一些例外)。

首先,你的数据库应该定期备份,所以你永远不应该因为DELETE而永久丢失数据(当然,除非是刚删除的数据)。

其次,像这样的软删除意味着您现在必须在该表的每个查询中包含WHERE IsDeleted = false子句(如果join这些表,那么更糟)。 一旦用户或testing者发现删除的logging再次出现,可能需要一些时间才会发现这里的错误。 另外,开发人员很容易忽略COUNT(*)查询中的WHERE子句,这可能需要更长的时间才能发现(我曾在一个项目发生多年的情况下工作,没有多lesslogging被“删除” ,所以总数接近预期,没有人注意到)。

最后,一个软删除将使用人工钥匙工作,但可能不会在具有自然主键的桌子上工作(例如,您从一个由社会保险号码键控的桌面上“删除”某个人 – 当您需要把他加回来吗?请不要说“include IsDeleted in a compound primary key”)。

在devise审查中,我希望开发人员能够展现出成本和收益的意识,并以这种方式为软删除提供一个很好的理由。 “为什么这样做?” 不是一个很好的理由。

避免潜在的数据丢失绝不是一个坏主意。

我总是软删除。 在数据库需要清理一个或多个logging的情况下,我通常采用软删除的两步过程,然后清空logging的“回收站”,或者采用文档pipe理方式,其中文档logging可以过时,然后在严格删除之前通过审批stream程。

这取决于情况。 我可以看到在法律上要求真正删除某些内容的情况。 也许有人要求将他们的社会安全号码从系统中永久删除。 或者,也许你有一个重复的logging,你想合并成一个logging。 保持挂着一个删除标志的副本可能不是有利的。

还有一个技术缺点:不能做级联删除,它会自动清除对已删除数据的任何引用,以防止外键违例。 这不一定是个大问题,但要记住。

否则,我认为这是个好主意。

如果您打算使用软删除,那么最好有一个deleted_date字段,而不是一个is_deleted字段。 你会得到一个额外的数据,而不是只是位字段。

软删除的一个主要问题是那些不需要的数据可能会影响数据库的性能。 几年前,我的一个客户端要求我对所有数据库项目进行软删除,我的解决scheme是将所有“已删除”项目移动到备份表格,而不是将其保留到当前正在运行的表格中。

当一个无效的删除是绝对灾难性的,恢复应该是简单的时候,这是个好主意。 如果你想跟踪一切,“删除”只是“隐藏”,这也是一个好主意。 意思是说,这取决于情况。

软删除还允许您从应用程序使用的数据库帐户中撤消 DELETE权限。

我不会试图在“政治上是正确的”。 如果你是主张软删除,那么你需要去大脑检查。

1)首先,你究竟是通过不删除表中的行来实现的? 只是在将来的某个时候你可以访问这些行,对吧? 那么为什么不直接创build一个存档表并在那里移动行呢? 那有什么问题?

2)使用软删除,您正在创buildis_active上的不必要的查询或在某个时间戳列上查询。 这只是浪费时,你会写更简单的查询。 是的,它将有一个观点,但意见不是一个额外的附件? 每个视图都是一个额外的SQL,额外的性能成本,在任何商业RDBMS下,一切都只是一张表。 除了不知道如何在表格上写查询之外,没有任何关于视图的神奇function。

3)是的,它将与视图或MV一起工作。 但是后来我看到在生产FTS的问题,一切仍然有效! 现代硬件和坚实软件的奇迹。 但是,那也不是正确的。 所以通过相同的逻辑,仅仅因为它的作用并不意味着它是正确的

4)软删除的复杂性永远不会停止在一个简单的select。

A)假设你有一个UNIQUE约束。 现在,您可以软删除一行,但是具有UNIQUE约束的列仍然存在。 当你想重新添加相同的数据时,你不能没有额外的“技巧”。

B)从表A到表B可能有关联,当你从表A中软删除某些东西时,你需要确保表B上的独立查询处理这个事实。 假设一个典型的细节页面正在处理一些detail_id。

现在一个master_id被软删除,但你仍然有永久性的master_id的detail_id的永久链接。 当您在master_id上进行硬删除时,这些细节根本就不存在。 现在软删除他们仍然存在,他们必须知道他们的master_id是在软删除模式的事实。

它不会停在一个简单的Table_A.is_active = 0或1阶段。

5)努力删除简单而正确。

A)没有人需要在任何地方添加任何额外的东西或担心任何事情。

  1. 您的应用程序逻辑更简单
  2. 你的数据库较小
  3. 您的查询速度更快

只是归档数据+相关的部分,你应该是好的。

有时候软删除是必要的。 例如,假设您有一个引用Products表的发票表。 一旦创build了具有特定产品的发票,您就可以永远不删除该产品(并且如果您的RI设置正确,则不会让您)。

这个特定的场景假设你永远不会想要删除发票,在真正的公司你可能不想删除历史财务数据。

虽然还有很多其他情况下,您将无法删除一些数据,作为依赖链的副作用,因为业务或其他原因不能删除。

这取决于数据。 由于法律/审计要求,某些数据不能删除。

另一方面,社交网站应该提供一个选项,用于删除包含联系信息,照片,消息等所有相关数据的帐户。如果他们没有,例如Facebook,这是一个真正的烦恼。

在oracle中,如果你将主键添加到一个recycle_bin表中,然后添加一个行级别的安全策略,当行在回收站中时,可以禁止所有查询的值,将回收站中的pk移除自动恢复所有数据。 不需要改变你的其他查询来适应逻辑。

但是,它会带来成本,因为您需要更新查询和索引才能排除已删除的行。

也许不是切换一个标志,而是将它移动到另一个“垃圾桶”表。

此外,可以说这只是一个部分的解决scheme,因为它只包含删除,但是当你更新一行时,你仍然覆盖旧的值。

一般来说,我会说永远不会删除任何东西,除非你真的必须。 磁盘空间现在很便宜。 当然,这是有限制的,有一些数据是你在法律上必须抹去的,有些数据实际上并不是那么重要,也许你不需要把旧的数据在线保存在同一个表格中也会工作)。

只要加一分钱。 我总是软删除; 虽然它的性能成本,但非常轻微。 当你的客户抱怨你的软件停止运作后,她执行了一些甚至她不记得的行为,想想成本。 那么这可能是一个很好的例子,但是你永远不会知道什么是错的,谁做了什么,之前是什么,之后是什么。 在这种情况下,这将派上用场。 这个function适用于审计目的,许多客户要求审计这种types的报告。

而且,在大多数基于工作stream程的应用程序中,它是作为软件function/要求,客户对在工作项目上执行的“操作”感兴趣; 分配了什么样的价值以及谁处理了这些价值等

我是软删除的粉丝。 主要是为了防止级联删除。 但是,它需要额外的代码,所以如果您select一个子对象,它会join到父对象(以及所有父对象)中,以确保它们都不被删除。 或者,您可以级联软删除,但如果稍后想恢复它们,则可能不知道哪些子级已被删除,哪些子级由于级联而被删除。

另外,我在每个对象上保留一个修订date时间和修订用户名,以便我知道谁修改了(或者软删除)了最后一个。 然后,对于审计跟踪,我创build一个*历史logging(如CustomerHistory)表,每个UPDATE后插入原始表。 这样在一个对象被修改或软删除后,我logging了谁执行了该操作以及该对象的最后一个已知状态。

我遇到了以下大范围的软删除操作:

案例1:删除logging从用户/代码可见,但有logging在数据库级别,因为业务有兴趣知道它有logging。
这些要求主要是由业务驱动,通常在核心可能是一个法律要求(如@joshperry&@armandino场景)有以前的logging在数据库中,并创build一个新的logging,每一个变化。 在这一点上,我会看情况2和评估是否符合要求之前有一个IsDeleted标志

案例2:审计追踪以追踪logging的演变 – 在线保存数以万计的体面的文章,用于保持数据库logging的审计跟踪

HTH。