数据库逻辑删除,唯一性约束究极解决方案

文章目录

  • 一、写在前面
  • 二、解决方案
    • 1、业务逻辑层面控制
    • 2、物理删除+数据归档
    • 3、is_delete !=0的都认为是删除(推荐)
    • 4、MySQL 函数索引(表达式索引)(需 MySQL 8.0+)(推荐)
    • 5、部分索引(Partial Index)(需 MySQL 8.0.13+)(推荐)

一、写在前面

平常开发中,有些表数据需要记录历史,如果物理删除就再也无法查到了,这个时候通常是创建一个删除标识字段(未删除:0,已删除:1)用于标识数据是否删除:

CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(100) COMMENT '姓名',`gender` varchar(20) COMMENT '性别',`address` varchar(255) COMMENT '地址',`id_card` varchar(255) NOT NULL COMMENT '身份证',`remark` varchar(255),`is_delete` varchar(255) COMMENT '是否删除',PRIMARY KEY (`id`)
) ENGINE=InnoDB;

但是通常数据库中的数据是需要进行兜底的,比如说身份证需要唯一,但是如果加上删除标志,就无法保证唯一性了。
但是如果身份证和删除标识,这两个字段加上唯一索引,用户多次删除的时候,也是不行的。
删除标识这个时候需要怎么做呢?

二、解决方案

1、业务逻辑层面控制

数据库不做唯一性索引限制,在业务代码中控制。

def create_user(username):# 检查未删除的记录中是否存在相同usernameexisting = db.query("SELECT id FROM user WHERE username = %s AND is_deleted = 0", username)if existing:raise ValueError("用户名已存在")db.execute("INSERT INTO user (username, is_deleted) VALUES (%s, 0)", username)

这样数据库无法兜底,并发操作需要加锁。

2、物理删除+数据归档

简单的方案就是做数据归档或者离线表。
就是说再创建一张user_record_his表,然后在用户删除时,在同一个事务中把user表中的数据插入到user_record_his中,然后再把user表中的记录删除:

insert into user_record_his;
delete from user where id=1;

还有一种归档方式是基于离线数仓,定时将用户信息进行同步,其中delete操作不同步,只同步insert、update。
这样的话,用户同一天删除又创建是有问题的,所以业务上通常会限制用户创建和删除的频率(3天一次)。

3、is_delete !=0的都认为是删除(推荐)

将id_card和is_delete设置为联合唯一索引。
正常数据的is_delete字段为0,如果执行删除操作,可以将该字段置为时间戳或者id。

update user set is_delete = '时间戳';
-- 或者
update user set is_delete = id;

该字段使用uuid、时间戳、递增都可以。

4、MySQL 函数索引(表达式索引)(需 MySQL 8.0+)(推荐)

创建基于表达式的唯一索引,仅对有效记录生效。

-- 原理:索引仅包含is_deleted=0时的username值,已删除记录的表达式结果为NULL(不参与唯一约束)。
-- 限制:MySQL 的函数索引要求表达式结果非NULL时才会被索引,需确保业务字段非空。
-- 或者 if((is_deleted = 1),NULL,1)
ALTER TABLE user 
ADD UNIQUE INDEX idx_unique_valid_idcard ((CASE WHEN is_delete = 0 THEN id_card END));-- 数据测试
INSERT INTO `user`(`name`, `gender`, `address`, `id_card`, `remark`, `is_delete`) VALUES ('张三', '男', '山东', '123', NULL, '0');
update user set is_delete=1 where id_card='123' and is_delete=0;

5、部分索引(Partial Index)(需 MySQL 8.0.13+)(推荐)

这个需要mysql版本支持,我不知道我的8.0.23版本为什么不支持

ALTER TABLE user
ADD UNIQUE INDEX idx_idcard_not_deleted (id_card) WHERE is_deleted = 0;

原理:索引仅覆盖is_deleted=0的记录,已删除记录不参与唯一性校验。
注意:MySQL 的部分索引功能在 8.0.13 + 版本支持,但实际使用时需验证兼容性(部分云数据库可能未完全开放)。

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

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

相关文章

3-存储系统

一-基本概念 二-主存储器 三-主存储器与CPU的连接 四-外部存储器 五-高速缓冲存储器 六-虚拟存储器

华为0528笔试

第三题 题目 给定一个二维数组 mountainMap 表示一座山的地图,数组中的每个元素 mountainMap[x][y] 代表坐标 (x, y) 处山的高度。登山员从山底出发,爬到山峰。 山底的含义:mountainMap中高度为0的坐标点。 山峰的含义:mountain…

Redis的过期策略和淘汰策略

Redis的过期策略和淘汰策略 想象一下周末的大型超市:生鲜区的酸奶贴着"今日特价"标签,促销员定时检查这些商品的保质期;而仓库管理员正根据"先进先出"原则整理货架,确保商品不会过期积压。这种高效的商品管理…

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …

【HarmonyOS 5】 影视与直播详以及 开发案例

&#x1f3a5; ‌一、超高清低延迟直播‌ ‌4K/8K硬解能力‌&#xff1a;通过鸿蒙媒体引擎实现15Mbps码率视频流稳定解码&#xff0c;华为Pura X实测端到端延迟<80ms‌分布式渲染‌&#xff1a;支持手机拍摄→智慧屏导播→平板监看的工作流协同&#xff0c;设备间传输延迟&…

Tunna工具实战:基于HTTP隧道的RDP端口转发技术

工具概述 Tunna是一款利用HTTP/HTTPS隧道进行TCP通信的渗透测试工具&#xff0c;由SECFORCE团队开发并开源。该工具主要应用于需要绕过防火墙限制的场景&#xff0c;通过Webshell实现内网服务的端口转发&#xff0c;特别适合在仅开放80/443端口的环境中建立TCP连接。 项目地址…

c# Autorest解析

AutoRest 工具生成用于访问 RESTful Web 服务的客户端库。AutoRest 的输入是使用 OpenAPI 规范格式描述 REST API 的规范。OpenAPI(f.k.a Swagger)规范代码生成器。支持 C#、PowerShell、Go、Java、Node.js、TypeScript、Python。 安装 AutoRest 在 Windows、MacOS 或 Linux …

高中数学联赛模拟试题精选学数学系列第24套几何题

⊙ O 1 \odot O_1 ⊙O1​ 和 ⊙ O 2 \odot O_2 ⊙O2​ 交于 A A A, B B B. Y Y Y 是 ⊙ O 1 \odot O_1 ⊙O1​ 上一点, Z Z Z 是 ⊙ O 2 \odot O_2 ⊙O2​ 上一点&#xff0c; Y Z YZ YZ 通过 A A A. 过 Y Y Y 的 ⊙ O 1 \odot O_1 ⊙O1​ 的切线和过 Z Z Z 的 ⊙…

【QT】INI格式文件读写类IniApi封装

【QT】INI文件读写类IniApi封装 前言实现INI文件写入方法INI文件读取方法 测试 前言 INI格式文件是一种纯文本格式&#xff0c;使用方括[]定义节&#xff08;Section&#xff09;&#xff0c;每个节下包含键值对&#xff0c;如下图所示。该格式文件简单易读易编辑。而且在所有…

ABAP设计模式之---“童子军法则(The Boy Scout Rule)”

法则介绍 The Boy Scout Rule&#xff0c;中文一般翻译为“童子军法则”&#xff0c;是一个简单却非常有意义的软件开发原则&#xff0c;它最早由软件开发大师 Robert C. Martin (Uncle Bob) 在他的《Clean Code》一书中提出。 这条法则的核心思想非常简单&#xff1a; “确保…

BaikalDB 架构演进实录:打造融合向量化与 MPP 的 HTAP 查询引擎

导读 BaikalDB作为服务百度商业产品的分布式存储系统&#xff0c;支撑了整个广告库海量物料的存储和OLTP事务处理。随着数据不断增长&#xff0c;离线计算时效性和资源需求压力突显&#xff0c;基于同一份数据进行OLAP处理也更为经济便捷&#xff0c;BaikalDB如何在OLTP系统内…

【抖音小程序】通用交易系统-下单问题整理

在通用交易系统中&#xff0c;支付流程如下 1、服务端-预下单&#xff1a;生成参数与签名信息&#xff08;此过程不需要与抖音平台对接&#xff09; 参考 生成下单参数与签名_抖音开放平台 2、小程序用户端&#xff1a;根据返回的参数与签名&#xff0c;拉起抖音支付&#x…

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…

EurekaServer 工作原理

一、核心工作流程 二、核心组件解析 1. 自动配置引擎 入口&#xff1a;EnableEurekaServer 引入 EurekaServerMarkerConfiguration&#xff0c;创建标记Bean Marker触发条件&#xff1a;EurekaServerAutoConfiguration 检测到 Marker 存在时激活关键Bean初始化&#xff1a; …

Playwright 与 Selenium:自动化测试的两大主流工具对比

《Playwright 与 Selenium&#xff1a;自动化测试的两大主流工具对比》 *Playwright 和 Selenium 是自动化测试领域的两大主流工具&#xff0c;二者在架构设计、功能特性和适用场景上存在显著差异&#xff0c;以下是核心对比&#xff1a; 一、架构与设计理念 维度Playwright…

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

R语言速释制剂QBD解决方案之二

影响含量均一性的显著因子&#xff08;%RSD&#xff09; 数据分析表明含量均一性的弯曲性不显著。如半正态图&#xff08;图12&#xff09;所示&#xff0c;影响含量均一性的显著因子为A&#xff08;原料药粒径&#xff09;和C&#xff08;MCC/Lactose&#xff09;。 mod2 <…

大模型原理、架构与落地

近年来&#xff0c;大模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;在人工智能领域迅猛发展&#xff0c;从GPT-3到GPT-4、Claude、Gemini、文心一言、GLM等模型相继发布&#xff0c;大模型已逐渐走出实验室&#xff0c;迈向产业落地。本文将从技术原理、…

WWDC 2025 macOS 26有哪些更新点

在2025年6月10日凌晨结束的WWDC 2025发布会中&#xff0c;苹果正式发布了全新的macOS 26&#xff0c;并给其命名为Tahoe。 以下为macOS相关的主要内容&#xff1a; 命名方式改变 苹果正式将各大系统的版本号改为对应年份&#xff0c;让命名方式更直观好记&#xff0c;macOS 2…

AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月10日第104弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀4-5个和值&#xff0c;可以做到100-300注左右。 (1)定…