唯一性索引与逻辑删除冲突问题解决思路

引言

今天做项目中遇到了一个问题:逻辑删除和唯一性索引同时存在的情况下,已经逻辑删除的数据由于唯一性索引的约束无法再次添加,该怎么办?

这个问题在之前做其他项目中也遇到过,当时并没有想到什么好的解决方法,也没有查资料,自己想了一个暴力方法:

我直接把唯一性索引去掉了,然后在代码逻辑实现部分用代码对唯一性索引字段进行了唯一性约束;

这当然也解决了问题,但是这样做本来就是不对的,设计好的数据库怎么能随意修改;

这次又遇到了一样的问题,想到上次的那种方法不仅不合规,而且非常麻烦(为了一个唯一性逻辑判断再调用数据库查询然后再写逻辑判断),这次就找了一下解决方法,下面简单介绍一下;

解决思路

所有解决方法就一个思路:通过逻辑删除字段和约束字段组合为一个索引;

比如有一张teacher表,唯一性索引为name,逻辑删除字段为is_delete:

image-20220630175439089

唯一性索引:

image-20220630175457484

为了解决冲突问题,首先需要修改一下索引,让逻辑删除字段和唯一字段一起作为索引:

image-20220630175652690

但是还需要注意一点:一般我们习惯把逻辑删除字段is_delete设为0存在1删除;但是这里就不能这样了;

比如删除上表中test字段,索引可以看为test和1的组合;再次创建test并不会出现问题,因为新创建的索引为test和0的组合,但是如果再次删除test那么就又出现test和1的组合,索引冲突;

所以我们唯一要做的就是想办法让逻辑删除字段的删除标识唯一,未删除字段不需要改变;

下面有三种方法:

删除标识设置为主键id

因为主键id是唯一的,所以只需要将逻辑删除字段的删除标识设置为主键即可:

image-20220630180739614

但是这种方法我认为如果id过长,会不会占用更多的空间?(个人想法)

就比如这个teacher表中我只把is_delete字段设置为tinyint长度为3,如果主键过长肯定需要修改为bigint,麻烦不说,是不是还占用了更多的空间;

image-20220630181029681

删除标识设置为当前时间

这个方法就类似与将删除标识设置为一个时间戳,因为每一段时间都是不一样的,所以自然也不会有重复一说:

那么获取时间可以使用mysql的Now()函数:

image-20220630181404408

但是这样同样也占用空间,并且该字段调用函数可能会影响sql效率;并不是特别推荐;

删除标识设置为NULL

这个方法就是把删除标识设置为NULL,可以完美解决该问题:

image-20220630181809102

我认为这个方法是最好的,我也是使用的这个方法;

image-20220630182134082

可以看到并不会产生冲突;

注意:逻辑删除字段is_delete要设置允许为null;

总结

我也见了其他方法:比如创建历史表、redis判重、新增字段与索引进行唯一约束…

但是这些方法感觉都没有直接修改来的方便,有点多此一举;

当然以上仅是个人观点,如果有问题欢迎交流;

汇总一下:
在这里插入图片描述

  • 12
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YXXYX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值