数据的软删除和物理删除

前言

不同的业务数据的删除需要不同的策略,一些需要永久保留,一些可以直接删除。

关系型数据

关系型数据库里面,一条记录的删除,根据业务需要,很大可能选择软删除,因为:

  • 数据完整性,相关数据可以保留
  • 历史数据查询,方便审计等
  • 速度快

因为删除一条被外键引用的数据,数据库系统会遍历相关数据,确保没有被引用才删除,所以有可能很慢,譬如用户表,一般会被大量业务表引用,物理删除用户可能会超时。

举个具体例子,一个商城,如果下架一个商品,不会做物理删除,因为所有历史订单、收据、报表等等都要层级删除,那严重破坏数据完整性。

又或者员工不爽,离职了,如果物理删除这个员工的记录,那所有和ta相关的数据都要被删除,那是不合理的。

所以这里,很多时候,不是做“删除”,而是做状态改变,所以我们称之为“软删除”。

时光机

另外,总会有手贱/失误的时候,如果要让DBA去找历史数据回来修复,那系统功能受影响的时间就受限于DBA了。

另外,关于数据有效性问题,历史数据未必是最新的,老数据一些时候比没有数据更糟糕。

软删除是后悔药,大大降低了损失的可能性。毕竟,你永远不知道哪天你又需要那条被删除的记录了。

坑s

当然,这样会带来几个问题。首先是有效数据的过滤问题。譬如现有的的用户列表逻辑,需要去掉被标记为删除的数据。这种情况,要么做个视图,要么逻辑加入过滤条件。

如果对标记字段(譬如IsDeleted: bool 或者Status: int),一般没有很好的entropy,所以不是很好的候选索引字段,但是我们可以做筛选索引(filtered idnex)来解决。

另外,需要考虑唯一主键,因为之前同一个业务只有一条记录,现在可以有多条(1条有效,n条被删除)。譬如用户表,软删除了用户Foo,那以后注册的用户就不能用Foo这个名字了。这种数据冲突比较麻烦,所以这样会对业务逻辑增加难度。

还有,数据不被物理删除,随着时间推移,会累积越来越多的数据,这个可能会带来几个问题:

  • 空间增加
  • CRUD速度下降(索引相关)

人工审核

有些公司有一定的流程,专人对被标记擅长的数据进行审查,确认这个数据是否真的应该被删除。

定时物理删除服务

其次,可以实现一个定时服务,在系统空闲的时候,删除那些被标记了的数据。

除了现有表做标记的软删除,其他做法如不原表留下,转到历史表,不过这种情况下外键约束就有层级关联问题要解决了,除非完全不用外键约束。

当然,除了历史表,还可以写到其它数据存储结构,譬如NoSQL等。

触发器

如果不写定时服务,可以考虑即时的表删除触发器,一般关系型数据库系统提供这个功能,当一条记录被删除的时候,会调用你定义的删除触发器逻辑,在这个触发器里面,你根据业务需求做各种操作,譬如把数据挪到历史表等。

数据保留期限

视乎具体业务需求和合规性要求,被标记软删除的数据,保留时间可以从1天到永久都有可能。

非关系型数据

非关系型数据库天生没有这种强约束的优势/烦恼,可以直接物理删除。

数据的安全

数据的保护和加密会在另外一篇文章详细讨论。

即便物理删除,我们也需要考虑,如欧盟的GDPR和一些国家的Privacy Act要求之前的数据备份也是需要删除的,这就对冷备份的数据有挑战了。

数据策略

总而言之,不同的公司不同的业务应该有不同的删除/保留/备份/安全策略,不能一概而论。数据管理的最终目标:

  • 准确性
  • 完整性
  • 安全性
  • 合规性
  • 性能

性能重要,但不是最重要的。关于性能,我对后端、数据库、云、整体架构有多年的实战经验,有兴趣的同学可以扫描右边二维码加我讨论。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。