当前位置: 首页 > news >正文

解决MySQL虚拟删除影响唯一索引的问题

场景

现在的项目一般使用逻辑删除来处理业务上的删除逻辑,这样方便数据的恢复和追溯,一般加一个 is_deleted 列,值为 0 说明没有没删除,值为 1 说明被删除了。

但是如果表中存在一个唯一索引,例如 name,第一次 insert 一条 {name: '张三', is_deleted: 0} 的数据,之后将这条数据删除,数据变成 {name: '张三', is_deleted: 1}

随后再次 insert 一条 {name: '张三', is_deleted: 0} 就会出现唯一索引冲突的问题,虽然逻辑上来说之前那条数据已经被删除,但是因为我们唯一索引是建立在 name 上,其并不识别虚拟删除列,

这时候是不是可以考虑将 nameis_deleted 做一个联合唯一索引?但是依然会有问题,如下:

  • + {id: 1, name: '张三', is_deleted: 0} 联合唯一索引: 张三 0

  • - {id: 1, name: '张三', is_deleted: 0} 联合唯一索引: 张三 1

  • + {id: 2, name: '张三', is_deleted: 0} 联合唯一索引: 张三 0

  • - {id: 2, name: '张三', is_deleted: 0} 联合唯一索引: 张三 1

    执行这一步删除时报错,因为上面第二步 id为1的已经产生了一个 张三 1 的唯一索引。

解决方式

思路很简单,就是将虚拟删除后的数据不纳入唯一索引管理范围内,因为删除后的数据也没用了,所以不纳入索引也无关紧要,本身就用不着,因此主要看数据库引擎是否支持这么做,mysql5.7和8分别有不同的支持方式。

mysql5.7

mysql5.7 支持使用一个虚拟列来做唯一索引,这个虚拟列可以加上条件判断,如果非虚拟删除时,列的值是name,否则就是null,这样可以达成我们上述的结果,保证没有被逻辑删除的数据被唯一索引约束着。

CREATE TABLE your_table (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),is_deleted TINYINT DEFAULT 0 COMMENT '0-未删除,1-已删除',name_for_unique VARCHAR(50) GENERATED ALWAYS AS (IF(is_deleted = 0, name, NULL)) VIRTUAL,UNIQUE KEY uk_name_active (name_for_unique)
);

mysql8

mysql8更直接一些,直接将条件判断带入索引中,无需新建虚拟列。

CREATE TABLE your_table (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),is_deleted TINYINT DEFAULT 0 COMMENT '0-未删除,1-已删除',UNIQUE KEY uk_name_active (name, (IF(is_deleted = 0, 0, NULL)))
);
http://www.dtcms.com/a/274109.html

相关文章:

  • 《PyWin32:Python与Windows的桥梁,解锁系统自动化新姿势》
  • 从0开始学习R语言--Day44--LR检验
  • 外媒:蚂蚁数科等科技公司在香港数字资产枢纽建设中显身手
  • python 在 Linux CentOS 上安装 playwright 的完整步骤
  • 【每日刷题】回文数
  • 【数据结构】8. 二叉树
  • 【LeetCode 热题 100】24. 两两交换链表中的节点——(解法一)迭代+哨兵
  • leetcode106深度解析:从中序与后序遍历序列构造二叉树
  • leetcode:518. 零钱兑换 II[完全背包]
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_congestion_control
  • (LeetCode 每日一题) 3169. 无需开会的工作日 ( 排序+贪心 )
  • 力扣_二叉搜索树_python版本
  • 1965–2022年中国大陆高分辨率分部门用水数据集,包含:灌溉用水、工业制造用水、生活用水和火电冷却
  • 【unitrix】 4.21 类型级二进制数基本结构体(types.rs)
  • 李沐动手学深度学习Pytorch-v2笔记【07自动求导代码实现】
  • 进程管理中的队列调度与内存交换机制
  • Jenkins 系统管理与配置
  • 排序算法与前端交互优化
  • 持续集成 简介环境搭建
  • 14 TryHackMe 靶场 Wireshark: The Basics
  • CIU32L051系列 DMA串口无阻塞性收发的实现
  • CentOS 安装 JDK+ NGINX+ Tomcat + Redis + MySQL搭建项目环境
  • Redis5.0.5 漏洞
  • redis的一些疑问
  • windows下安装 redis
  • Redis全栈技术导航:从基础架构到实战案例的完整指南
  • 创客匠人:AI 时代创始人 IP 打造与知识变现的范式迁移
  • 什么是IP关联?跨境卖家如何有效避免IP关联?
  • LeetCode--43.字符串相乘
  • 软件过程模型核心特征与开发流程对照表