數據庫邏輯刪除,唯一性約束究極解決方案

文章目錄

  • 一、寫在前面
  • 二、解決方案
    • 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
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84305.shtml
英文地址,請注明出處:http://en.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)定…