数据库的逻辑删除
数据库的逻辑删除,是相对于物理删除的。
数据无价,一旦物理删除,不考虑通过 binlog、其他技术手段等的话,很难找回。
逻辑删除的方式是设置一个删除字段,我们称之为 is_del
,初始值为 0。
如果用户删除数据,我们把 is_del
字段设置为 1,在查询时,忽略 is_del
字段为 1 的数据 ,从而达成用户感知为数据已删除,但是数据还实实在在存在数据库的效果,这就是逻辑删除。
逻辑删除和唯一索引的冲突
设想一个场景,数据表 user
的 username
字段是唯一的,即不可重名。
为了保证这个字段的唯一性,我们为 username
字段添加唯一索引 unique。
这时张三注册了一个账号,username
字段为张三。
有一天张三注销了账号,我们把张三那行数据的 is_del
字段设置为 1。
然而张三半个月后回来了,仍旧注册用户名为张三,却提示注册失败。
这是因为唯一索引检索到 username = 张三
的记录是存在,这显然不符合我们的日常逻辑。
解决方案
我们需要保证逻辑删除的数据不影响唯一索引的效果。is_del
我们不再只存 0 和 1,而是修改为删除时的时间戳,然后建立联合唯一索引 uk(username, is_del)
。
这样就算张三注销再多次账号,因为逻辑删除的时间不一样,也不会造成唯一索引冲突了。