关系型数据库一般是存储客户的业务数据,这部分数据非常重要,如果物理删除了,想找回来需要的成本较高,而且定位很多问题时,因为数据已经被删除了,导致定位起来也比较麻烦。所以没有特殊情况下,一般不建议做物理删除,所以表设计的时候需要有字段标识记录是否删除。
传统的方案:
增加is_del字段,0表示未删除 1表示删除
这种方案存在的问题:
对于大部分情况,这种方案是没有问题的,但是有一些情况,唯一索引可能会存在冲突,导致新增数据可能会违反唯一键冲突。以用户工资表为例:
这个表的唯一索引应该是user_id+date+is_del,每个员工一个月只能有一条记录,如果工资计算错了,需要重新计算,那么旧的数据就需要删除,is_del=1,如果重新计算多次就会有多条is_del=1的记录,唯一键冲突,就会报错,这种情况下传统的方式会存在问题。
比较通用的方案:
以card表举例:
其中del字段只做删除和非删除状态判断,业务表自己的status字段与这个独立,不要混淆在一起。
新增是del默认就是0
删除的时候从delete语句改为update
原:
delete from card where cd_id='123456';
改为逻辑删除:
update card set del=id where cd_id='123456' ;
或者update card set del=#{当前时间戳} where cd_id='123456' ;
注意影响点:
1.对唯一索引的影响
以上面的card表为例,如果唯一索引为cd_id,修改为逻辑删除后唯一索引要变成:cd_id+del,如果这个唯一索引每次新建都是不一样的(uuid),那唯一索引可以保持不变,建议最好按照这种建立唯一索引
2.对查询的影响
基本所有的查询语句默认都需要加del=0的查询条件