首页 > 其他分享 >如何建立含有逻辑删除字段的唯一索引

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

时间:2023-04-15 19:11:07浏览次数:33  
标签:name 删除 deleted 索引 字段 NULL id

文章目录

业务场景

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

分析

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

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。

 

标签:name,删除,deleted,索引,字段,NULL,id
From: https://www.cnblogs.com/huozhonghun/p/17321673.html

相关文章

  • Mysql索引
    索引优化速度首先创建了一个数据库,并创建了一个表,里面有800w条记录对其中的一条记录进行查询,使用了4.5s此时存储这个表的文件已经有500M的大小了添加索引后发现,刚刚存储表的文件变大了,变成了655m索引需要占用磁盘空间索引创建使用索引查询我们创建索引只对创建......
  • mysql如何查询所有表和字段信息
    1MySQL中information_schema是什么information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。元数据:元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据字典”和“系统目录”。在MySQL中,把informat......
  • 第8章_索引的创建与设计原则
    1.索引的声明与使用1.1索引的分类MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。从功能逻辑上说,索引主要有4种,分别是普通索引、唯一索引、主键索引、全文索引。按照物理实现方式,索引可以分为2种:聚簇索引和非聚簇索引。按照作用......
  • JAVA 循环删除list中元素的方法总结
    摘要:介绍List集合实现元素边遍历边删除的方法,例如removeIf和迭代器iterator.remove()等。综述  List集合是我们开发中经常使用到的一种集合形式,有时候会遇到在遍历List集合时需要删除指定的元素。但在根据条件使用for循环或者增强的for循环遍历删除某些元素时却不能随心所欲地......
  • 如何在Linux中安全的删除文件和目录
    导读在大多数情况下,我们习惯于使用Delete键、垃圾箱或rm 命令从我们的计算机中删除文件,但这不是永久安全地从硬盘中(或任何存储介质)删除文件的方法。在大多数情况下,我们习惯于使用Delete键、垃圾箱或 rm 命令从我们的计算机中删除文件,但这不是永久安全地从硬盘......
  • 删除无效的括号(广度优先搜索、字符串)、计算右侧小于当前元素的个数(树状数组、线段
    删除无效的括号(广度优先搜索、字符串)给你一个由若干括号和字母组成的字符串s,删除最小数量的无效括号,使得输入的字符串有效。返回所有可能的结果。答案可以按任意顺序返回。示例1:输入:s="()())()"输出:["(())()","()()()"]示例2:输入:s="(a)())()"输出:["(a())()","(......
  • SpringBoot 集成 MybatisPlus 九——逻辑删除
    1逻辑删除的概念逻辑删除不会在数据库中删除数据,只是通过一个字段用来标识被删除的记录,数据仍然保存在数据库中。在实际的工作当中,因为数据非常重要,为了防止因用户误操作删除数据后无法恢复的问题,我们通常不会对数据做物理删除,即将数据从数据库中直接删除。而是多采用逻辑删除的方......
  • sql pivot 多值, oracle pivot 行转列多个字段
    --povot单值点击查看语句select*from(selectt_bcr,t_bcrq,t_sjzfje,t_qs,t_groupfromlichtest_tb_a)t1pivot(min(t_sjzfje)fort_qsin(第一期,第二期,第三期))p--povot多值点击查看语句select*from(selectt_bcr,t_bcrq,t_sjzfje,t_sj......
  • MySQL学习笔记-索引
    索引索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。无索引的查找:全表扫描(将整张表遍历一遍),性能......
  • oracle查找重复数据和删除重复数据sql
    查找重复数据sql(思路就是根据需要判断重复数据的字段分组,根据having大于2的就是重复的)--查找某表重复数据selectBUSS_TYPE_ID,BUSS_TYPE,TRADE_VARIETY_ID,TRADE_VARIETY,TRADE_SUBVARIETY_ID,TRADE_SUBVARIETY,......