如何建立含有逻辑删除字段的唯一索引

news2025/1/21 18:45:50

文章目录

  • 业务场景
  • 分析
  • 解决
  • 总结

业务场景

在实际工作当中,遇到一个场景,就是在用户注册时,名字要全局唯一,当然,我们是可以对用户进行删除的,你会怎么去做?

分析

一般来说,我们可以在用户注册请求时,进行查库校验,看看名字是否已经存在,如果存在就抛异常给提示;否则,就落库。
除此之外,还可以直接给数据库字段加唯一索引

UNIQUE KEY `name_index` (`name`) USING BTREE

当前这种需要根据实际情况分析:

  • 如果我们删除用户是物理删除,就是直接delete,没问题
  • 如果我们删除用户是逻辑删除,相对于update数据的删除标识为1,这时候你怎么建唯一索引?
    针对第二种情况,可能很多人会说,把删除标识字段也加到索引里面,类似
NIQUE KEY `name_index` (`name`,`is_deleted`) USING BTREE

这里会有问题,当我们进行相同用户第二次删除之后,把id=3的数据删除(逻辑),修改is_deleted=1,此时就会报错,如下图

+----+---------+-----------+
| id | name    | is_deleted |
+----+---------+-----------+
|  1 | forlan0 |         0 |
|  2 | forlan1 |         1 |
|  3 | forlan1 |         0 |
+----+---------+-----------+

唯一索引不通过
那么,针对逻辑删除这种情况,怎么处理?

解决

1、删除时,修改is_deleted=主键

UPDATE forlan SET `is_deleted` = id WHERE `id` = 3;
--修改后的数据如下
+----+---------+------------+
| id | name    | is_deleted |
+----+---------+------------+
|  1 | forlan0 |          0 |
|  2 | forlan1 |          2 |
|  3 | forlan1 |          3 |
+----+---------+------------+

2、删除时,修改is_deleted=null
这种做法,不是会有两条相同的数据?下面的情况允许存在?

UPDATE forlan SET `is_deleted` = NULL WHERE `id` = 3;
--修改后的数据如下
+----+---------+------------+
| id | name    | is_deleted |
+----+---------+------------+
|  1 | forlan0 |          0 |
|  2 | forlan1 | NULL       |
|  3 | forlan1 | NULL       |
+----+---------+------------+

Mysql官方文档的解释

A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. This constraint does not apply to NULL values except for the BDB storage engine. For other engines, a UNIQUE index allows multiple NULL values for columns that can contain NULL.

其实大概意思就是,除BDB存储引擎外,此约束不适用于NULL值。对于其他引擎,UNIQUE索引允许包含NULL的列有多个NULL值

为什么允许这么搞?
我的理解是,NULL其实就表示未知,未知的东西,无法进行判断;如果NULL对唯一索引起作用,那么就会导致只能有1行数据为空,我们的业务场景,可能需要用NULL去表示未知或不确定的值。

当前,还是不太建议使用NULL,可能存在一些其它问题,比如:

  • 数据丢失
    阿里巴巴规范里面也说了,count(*) 会统计值为 NULL 的行,而 count(列名) 不会统计此列为 NULL 值的行
    WHERE条件!=不会查到NULL的值
  • 程序空指针报错,比如我们使用SUM(cloumn),如果字段都为NULL,最终返回NULL
  • 增加查询难度
    查询时,语法需要使用IS NULL 、IS NOT NULL、IFNULL(cloumn) 而传统的 =、!=等就不能使用了

3、新建一个字段delete_id,删除时,修改delete_id=主键
正常来说,其实1,2种方案已经满足,为什么我们要使用这种?
假设我们的表已经上线使用了一段时间,这时我们需要建唯一索引,就可以采取方案,实际上就是在删除的时候,多更新一个字段

UPDATE forlan SET `is_deleted` = 1,delete_id = id WHERE `id` = 3;

总结

有3种数据库层面的解决方案:

  • 删除时,修改is_deleted=主键
  • 删除时,修改is_deleted=null
  • 新建一个字段delete_id,删除时,修改delete_id=主键

至于怎么选择,看业务场景:
如果是已经投入使用的业务,可以采取方案3,否则可以采取方案1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/414255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java语法理论和面经杂疑篇《八. File类和IO流》

目录 1. java.io.File类的使用 1.1 概述 1.2 构造器 1.3 常用方法 1、获取文件和目录基本信息 2 列出目录的下一级 3 File类的重命名功能 4 判断功能的方法 5 创建、删除功能 1.4 练习 2. IO流原理及流的分类 ​编辑 2.1 Java IO原理 2.2 流的分类 2.3 流的API …

5.基于多能互补的热电联供型微网优化运行

说明书 代码相关资源:风、光、负荷场景生成;风电出力各场景及概率;光伏出力各场景及概率;负荷各场景及概率;场景的削减;样本概率初始化;样本削减 风电场风速两参数weibull(威布尔)分布的MATLA…

干翻Hadoop系列之:Hadoop前瞻之分布式知识

前言 一:海量数据价值 二:海量数据两个棘手问题 1:海量数据如何存储? 掌握分布式存储数据的思想。 A:方案1:单机存储磁盘不够加磁盘 限制问题: 1:一台计算机不能无限制拓充 2&a…

tomcat安装与配置

目录 1、安装jdk(官方站点下载 jdk-8u60-linux-x64.tar.gz ) 2、安装tomcat(官方站点下载apache-tomcat-8.5.20.tar.gz) 3、在浏览器上输入http://192.168.88.144:8080 4、写一个启动关闭的服务脚本 5、布置jpress应用 6、浏览器地址栏输入http://192…

真正的ChatGPT平替产品:Claude

01 Claude ChatGPT已经流行了很长的时间了,但是ChatGPT 由于种种的限制,我们无法用上,也有很多的平替产品,但是这些平替产品也有很多的问题。 现在 Claude 出来了,没有任何的限制。 Claude 不用魔法,注…

go test main包报错

前言 先提出问题, 再说明原因. 有如下一段代码: 当执行go test测试时, 会报如下错误: main.test /var/folders/55/47pl3jxx6rg7m0r6xvn4f7wr0000gn/T/go-build2769402238/b001/_testmain.go:13:8: could not import main (cannot import “main”) FAIL main [build failed] 什…

Linux文件类型详解

在Linux中一切都是文件,但文件都得有类型。那如何查看文件是什么类型了?在Linux中可以使用以下命令 ls -l path在显示文件的属性通常会以如下形式进行显示: drwxr-xr-x第1个字母:代表文件类型 第2~4字母:代表用户的权…

Dell戴尔笔记本电脑G5 SE 5505原装出厂Windows10系统恢复原厂oem系统1909

Dell戴尔笔记本电脑G5 SE 5505原装出厂Windows10系统恢复原厂oem系统1909 链接:https://pan.baidu.com/s/1imNdbSvxEqbMI3ODo-K3qQ?pwdhdez 提取码:hdez

Kubernetes安全加固

本博客地址:https://security.blog.csdn.net/article/details/130034953 一、认证安全配置 1.1、X.509客户端证书 X.509客户端证书是目前用户最常用的认证安全配置方式,其也可称作HTTPS证书认证,是基于CA根证书签名的双向数字证书认证方式…

论文精读1:(网格特征)In Defense of Grid Features for Visual Question Answering(CVPR2020)

马萨诸塞州立大学阿默斯特分校Facebook 人工智能研究 目录1. Introduction2. Related WorkVisual features for vision and language tasksPre-training for VQARegions vs. grids.3. From Regions to Grids3.1. Bottom-Up Attention with RegionsRegion selectionRegion featu…

5年测试被裁,恶补3个月上岸字节28K,面试差点被问哭···

我的个人背景非常简单,也可以说丝毫没有亮点。 学历普通,计算机专业二本毕业,毕业后出来就一直在一家小公司,岁月如梭细,算了下至今从事软件测试已经5年了,也点点点了五年,每天都是重复的工作&…

大数据4 - 分布式计算

1.分布式计算概述 分散->汇总模式: 1. 将数据分片,多台服务器各自负责一部分数据处理 2. 然后将各自的结果,进行汇总处理 3. 最终得到想要的计算结果 1. 什么是计算、分布式计算? •计算:对数据进行处理&#x…

git版本规范-前端

前言 本文档适用于前端的小伙伴。针对目前前端只有测试环境和生产环境,为更好管理前端代码和适用于自动化部署,编写次文档,有不同意见的小伙伴可以进行讨论。 分支 由于没有目前没有预发环境,简化开发、测试、部署和发布流程&a…

W80X|联盛德|nulllab空想实验室|Arduino适配|学习(6):w80x_arduino环境安装

文章目录概述官方推荐安装方法(实测未成功)readme中的安装步骤:手动安装方法:clone项目至本地手动新建w80x_arduino管理器存放目录w80x_arduino开发进展说明概述 此开源项目由nulllab空想实验室团队维护,并得到联盛德…

STL基本概念

📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程&…

vue3+TS+Pinia+Vite项目实战之一

文章目录一、创建项目1.1 使用脚手架创建项目1.2 初始化项目二、登录页面的开发三、使用vite-plugin-mock模拟后台接口返回数据四、前端调用后端接口使用axios五、首页layout六、动态菜单七、设置需要登录才能访问某些页面一、创建项目 1.1 使用脚手架创建项目 npm init vuel…

【网络安全】SQL注入--报错注入

报错注入报错注入定义代码展示常用的报错语句1.获取数据库名称2.获取mysql账号密码3.获取表名4.获取字段名5.获取账号密码报错注入定义 报错注入:利用sql语句的不规范,获取相关sql提示信息 代码展示 常用的报错语句 select first_name, last_name FROM…

【小程序】django笔记2

templates路径除了在settings中的templates的DIR[]中申明还有什么别的方法?已知,django底层根据app注册顺序查找各app文件中的templates文件夹,在其中搜索目标模版文件。已知,app注册在settings中的INSTAll-APPS里。已知&#xff…

MyBatis基础增删改查

文章目录MyBatis1. MyBatis是什么?2. 为什么要学习MyBatis3. 第一个MyBatis环境搭建1)添加MyBatis框架支持2)配置MyBatis相关配置文件3)添加代码4. 解决类的属性名和数据表字段名不一致(resultMap)5. 增加操作1)返回受影响的行数2)返回自增的id6. 修改操作7. 删除操…

类和对象深入讲解(1)

目录 1.类和对象的初步认识 1.1面向过程和面向对象的区别 1.2类的引入 1.3内的定义 1.4类的访问限定符及封装 1.4.1访问限定符 1.4.2 封装 1.5类的作用域 1.6类对象模型 1.6.1如何计算类对象大小 1.类和对象的初步认识 1.1面向过程和面向对象的区别 C语言是面向过程的…