软会删除一个好主意还是一个坏主意?
不是实际删除数据库中的记录,而是将其标记为IsDeleted = true
,并且在恢复记录后,您可以将其标记为False
。
这是个好主意吗?
最好是物理删除记录,然后将其移动到存档数据库,如果用户想要记录回来,那么软件会在存档中查找记录并重新创建它吗?
答案 0 :(得分:100)
我说这是一个坏主意,一般来说(也许有一些例外)。
首先,您的数据库应该定期备份,因此您永远不会因为DELETE而永久丢失数据(当然,除非删除刚刚添加的数据)。
其次,像这样的软删除意味着你现在必须在这个表的每个查询中包含一个WHERE IsDeleted = false
子句(如果你正在加入这些表,那就更糟了)。一旦用户或测试人员发现删除的记录再次出现,就会发现这里的错误,这可能需要一些时间。此外,开发人员很容易从COUNT(*)查询中省略WHERE子句,这可能需要更长的时间才能发现(我曾在一个已经发生多年的项目上工作过;没有多少记录被“删除” ,所以总数接近预期,没有人注意到。)
最后,软删除将在带有人工键的表上工作,但可能无法在具有自然主键的表上工作(例如,您从社会安全号码键入的表中“删除”某人 - 您是什么人当你需要将他添加回去时?请不要说“在复合主键中包含IsDeleted”。)。
在设计评审中,我希望开发人员能够展示成本和收益的意识,并以这种方式呈现优秀的理由进行软删除。 “为什么不这样做?”不是一个很好的理由。
答案 1 :(得分:93)
避免潜在的数据丢失绝不是一个坏主意。
我总是软删除。在需要擦除一个或多个记录的数据库的情况下,我通常采用两步软删除过程,然后清空记录的“回收站”,或文档管理式方法,其中文档记录可以被老去,然后在硬删除之前经过批准程序。
答案 2 :(得分:32)
这取决于具体情况。我可以看到法律要求您真正删除某些内容的情况。也许有人要求将您的社会安全号码从您的系统中永久删除。或者您可能有一个重复记录要合并到一个记录中。使用已删除的标志保持副本可能没有用处。
还有一个技术缺点:您无法执行级联删除操作,这会自动清除对已删除数据的任何引用以防止外键冲突。这不一定是个大问题,但要记住这一点。
否则,我认为这是一个好主意。
答案 3 :(得分:24)
如果您要使用软删除,最好使用deleted_date字段,而不是is_deleted字段。你得到了一个很好的额外数据,而不仅仅是位字段。
答案 4 :(得分:20)
软删除的主要问题之一是那些不需要的数据可能会影响数据库性能。几年前,我的一个客户端要求我对所有数据库项进行软删除,我的解决方案是将所有“已删除”项目移动到备份表,而不是将其留给当前运行的表。
答案 5 :(得分:17)
如果无效删除绝对是灾难性的,并且恢复应该很简单,那么这是一个好主意。如果你想跟踪曾经发生过的事情,这也是一个好主意,“删除”实际上只意味着“隐藏”。意思是,这取决于具体情况。
答案 6 :(得分:9)
我不会试图“在政治上正确”。如果你提倡软删除,那么你需要进行大脑检查。
1) 首先,通过不删除表中的行,您到底实现了什么?事实上,将来某个时候你可以访问这些行,对吧?那么为什么不创建一个存档表并在那里移动行?这有什么问题?
2) 使用软删除,您将在is_active上创建不必要的查询或在某个时间戳列上创建查询。当你编写更简单的查询时,这只是浪费。是的,它可以用于视图,但是视图不是额外的附属物吗?每个视图都是一个额外的SQL,额外的性能成本,在任何商业RDBMS中都只是一个表。除了你不知道如何在表格之上编写查询这一事实之外,没有任何神奇的观点。
3)是的,它可以使用View或MV。但后来我看到生产中的查询做FTS,一切仍然有效!现代硬件和固体软件的奇迹。但那也不是正确的。因此,通过相同的逻辑,仅仅因为它起作用并不意味着它是正确
4)软删除的复杂性永远不会在简单的选择中停止。
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)没有人必须在任何地方添加任何额外的东西或担心任何事情。
只需归档数据+相关部分,你应该很好。
答案 7 :(得分:8)
软删除还允许您从应用程序使用的数据库帐户获得revoke DELETE
个权限。
答案 8 :(得分:5)
有时需要软删除。例如,假设您有一个引用Products表的Invoice表。一旦您创建了具有特定产品的发票,您就永远不会删除该产品(如果您的RI设置正确,它将不会让您)。
此特定方案假定您永远不想删除发票,在真实公司中您可能不想删除历史财务数据。
虽然在许多其他情况下,您无法删除某些数据作为依赖关系的副作用,但由于业务原因或其他原因,该链无法删除。
答案 9 :(得分:4)
这取决于数据。由于法律/审计要求,某些数据无法删除。
另一方面,社交网站应该提供删除包含所有相关数据的帐户的选项,包括联系信息,照片,消息等。如果他们不这样做,那将是一个真正的烦恼,例如主页。
答案 10 :(得分:4)
在oracle中,如果将主键添加到您组成的recycle_bin表中,然后添加行级安全策略,则可以在行位于回收站中时禁止所有查询中的值,从中删除pk回收站将自动恢复所有数据。无需更改其他查询以适应逻辑。
答案 11 :(得分:3)
它带来了成本,因为您需要更新查询和索引才能排除已删除的行。
也许不是切换标志,而是将其移到另一个“垃圾桶”表。
另外,可以说这只是一个部分解决方案,因为它只涵盖删除,但是当您更新行时,您仍然会覆盖旧值。
一般来说,除非你真的需要,否则我永远不会删除任何东西。这些天磁盘空间很便宜。当然,有限制,有法律命令要删除的数据,有些数据实际上并不是那么重要,也许你不需要将旧数据保存在同一个表中(在某个地方存档)也会有效。)
答案 12 :(得分:1)
只需加一分钱。我总是软删除;虽然它确实耗费了性能,但非常轻微。考虑一下成本,当您的客户抱怨您的软件在执行某些甚至无法记住的操作后停止运行时。嗯,这可能是一个很好的例子,但你永远不知道出了什么问题,谁做了什么,之前做了什么以及之后插入了什么。在这种情况下,这将派上用场。此功能可用于审计目的,许多客户要求审计此类报告。
此外,在大多数基于工作流程的应用程序中,它作为软件功能/要求,客户对在工作项上执行的“操作”感兴趣;分配了什么值以及处理它的人等等。
答案 13 :(得分:0)
我是软删除的粉丝。主要是为了防止级联删除。但是,它需要额外的代码,因此如果您正在选择子对象,它将连接到父对象(和所有父对象!)以确保它们都不会被删除。或者,您可以级联软删除,但如果您想稍后恢复它们,您可能不知道哪些子项已被删除,哪些子项因级联而被删除。
此外,我在每个对象上保留修订日期时间和修订版用户名,以便我知道最后修改(或软删除)了谁。然后,对于审计跟踪,我创建一个* History(如CustomerHistory)表,该表在每次UPDATE到原始表之后插入。这样,在修改或软删除对象后,我会记录执行操作的人员以及对象的最后已知状态。
答案 14 :(得分:0)
我遇到了以下广泛情况的软删除:
案例1:从用户/代码中删除记录,但记录在数据库级别,因为业务有兴趣知道它有该记录。
这些要求主要由业务和业务驱动。通常在核心可能是一个法律要求(如@joshperry& @armandino情景),以便在数据库和数据库中有先前的记录。为每个更改创建一个新记录。在这一点上,我会看看案例2&评估它是否在具有IsDeleted标志之前满足要求
案例2:跟踪记录演变的审计跟踪 - 在线有大量体面的文章用于保存数据库中记录的审计跟踪
HTH。