在现实世界中,有些文档用不到了、过期了,我们直接把它放入碎纸机碎掉,而有些文档需要保存到档案室,供以后查询。
一条订单,引用了很多其他信息,例如卖家信息、买家信息、商品信息等,当某种商品被下架时,我们也不能直接物理删除商品信息,否则引用它的订单的信息就不完整了。
对于要做假删除的那些表(在MongoDB中叫作“集合”):
- 方法一,可以增加一个is_deleted、is_active等字段来标识这行数据是否被假删除了。
- 方法二,可以专门为要做假删除的每张表建立一张对应的归档表(回收站表),把要删除的数据行先插入到归档表(包含删除时间、删除人ID、删除人姓名等额外字段),再在源表里删除。
方法一的缺点很多大神已经讲清楚了:
方法二更容易实现,对源表没有侵入性破坏,缺点只是增加了磁盘空间的开销。
我们设计数据库时,要视具体应用场景具体分析:
一、视具体业务的需求而定
如果业务问题是要备份数据,那应该做的是数据库备份,不应该是假删除。
如果业务问题是要归档数据,那应该做的是归档数据,也就是把数据移到归档表里。
如果业务问题只是想冻结数据,应该做inactive标记,这样在语义上非常完美,一致性约束同样没有问题。注意,“冻结”不是“删除”,“冻结”的意思是是这条数据如果你要再次用到,解冻它即可;而“删除”的意思是是这条数据已经被删除了,如果你要再次用到它,只能重新创建一条数据。
二、视数据库软件系统的类型而定
有些数据库软件系统已经帮你实现了归档数据的功能,例如SQL Server有历史表的功能,删除的记录自动记录到历史表里,更新操作也会把更新前的记录保存到历史表里。那么我们就无需自己创建归档表并在代码层面实现归档逻辑了。
三、视表中的数据类型而定
对于菜单表(字典表)、流水表(例如日志表),就无需做假删除了,因为没有必要,直接物理删除即可。
只有一些存储了重要数据的表,例如账户表、余额表,才要做假删除,也许使用回收站表的做法更好。
参考
https://www.zhihu.com/question/39967106/answer/121674339 注意,知乎现在需要登录才能查看到原文,否则显示的是一段随机文本,这是知乎应对AI大模型的爬虫的反爬措施。