在后台开发的时候,我们经常会碰到一些不能重复的字段,这些字段我们一般会设置 unique
唯一,毕竟仅仅通过服务端查询判断是无法保证字段实际存储唯一的,因为会存在并发问题,然后就是我们碰到的问题,当假删一条数据之后,那么这个 unique
字段就会被占用,如果还想继续使用删除的字段,那么怎么办呢?
可以集思广益一下,目前个人就想到了几种常见的方案(个人能力有限,就想到几种方向)
- 将原来的
unique
字段内容替换成其他的(例如带时间的),标记为已删除即可,即使恢复也可以恢复,缺点是有些记录如果保存的是关联,要关联显示出来的字段就是更新后的,由于内容变了,可能会懵逼;当然很多牺牲空间换时间的优化操作会保存一个历史值,无论维不维护这个值,都不影响结果显示,这个很常见
- 使用
复合约束功能 unique
即可,typeorm @Unique([])
、prisma则是@@unique([])
,通过这个属性和删除标记复合,这样标记删除后,他们的unique
结果就变了,这样新创建或者更新的就可以用这个值了,这也是比较常用
的手段,缺陷是要是恢复取消假删,得重新改成新的值才行,如果再删除一个同样的值,那么删除的会重复,实际上可以把假删的类型设置为数值而不是布尔,删除后可以通过自增解决(嫌麻烦可以再添加一个复合字段,默认为一个值,删除后传入一个时间戳也行),这个好处是没有优化历史记录的情况下,需要查看历史记录的时候,仍然可以看到最原始的结果 - 将删除的内容
迁移到另外一张表
中,无论是查询、还原等操作,都可以做到,并且不冲突,由于部分业务不知道这条数据删没删,如果具备历史记录功能,没有保存实际数据的可能拿不到,那么需要自行调整查询实现方案或者调整业务 - 碰到一些没有保存比较的表格(即使作为历史记录也基本不建立关联的那种),数据价值不大,直接
真删
(必要时备份到另外一张表,这样和3一样了),问题很小 - 数据库
不设置 unique
,服务端通过加锁
等方式查询未删除的是否重复,不重复就创建,重复就不创建,效率个人感觉较低,一般很少这么做吧,不太好控制,关键是慢,尤其是分布锁更慢(当然对于单个服务器这个看自己,一个表在多个数据库据库这种不太了解,没碰到过,可能使用类似的分布锁等解决吧,没碰到过) - 跟上面一种类似,不过乐观式写法,不写 unique,仅仅通过服务器调用查询判断是否存在而创建,这种也不是不行,要针对于人比较少,基本上不能同时操作的,那么就没事,或者即使重复了,也是小概率的问题,这个不在考虑范围之内,某种情况下也算一种解法,效率还高,毕竟适合的就是最好的
大家还有什么好手段么,想到什么可以讨论一下,毕竟个人感觉自己比较菜的,需要互相学习,这不才算是刚开始😂,当然这篇文章可能也是一个开始😂