數(shù)據(jù)庫邏輯刪除的解決方案探討

為什么我會(huì)看到這篇文章?

你可能是一個(gè)程序員,在簡書的搜索框上輸入了“數(shù)據(jù)庫邏輯刪除解決方案”并點(diǎn)擊了搜索按鈕。

- 本文章有很多廢話,如果不想看直接拉到底部 -



我遇到什么問題了?

在進(jìn)行數(shù)據(jù)庫設(shè)計(jì)時(shí),你的公司認(rèn)為數(shù)據(jù)對(duì)于公司來說存在重大意義(即便是已經(jīng)刪除的數(shù)據(jù)),因此你被強(qiáng)制要求對(duì)于數(shù)據(jù)的刪除只能使用邏輯刪除,即增加一個(gè)標(biāo)記字段來記錄該數(shù)據(jù)的刪除狀態(tài)。

你遇到了這樣一個(gè)場景,你的某個(gè)字段需要添加唯一鍵約束,因此你可能想了個(gè)辦法,用業(yè)務(wù)來控制唯一鍵。例如你的數(shù)據(jù)表中name是唯一的,現(xiàn)在你需要插入一條name = a的記錄:

然而你的服務(wù)運(yùn)行了一段時(shí)間后你還是發(fā)現(xiàn)了數(shù)據(jù)庫中存在 name = a 且 is_delete = 0 的多條字段,大部分是由于以下原因:


你發(fā)現(xiàn)在業(yè)務(wù)層面這個(gè)問題似乎是無法避免的,于是你開始考慮從數(shù)據(jù)庫層面避免該問題。你決定在name字段添加唯一鍵約束,但很快就否定了這個(gè)想法,因?yàn)檫@樣根本沒法進(jìn)行刪除,所以你開始在網(wǎng)上尋找解決辦法。



有沒有解決這個(gè)問題的辦法?

百度、谷歌幫幫我。

在網(wǎng)上搜尋很久以后,我看到了簡書上一篇比較好的文章:邏輯刪除真的不是一個(gè)好的設(shè)計(jì)。該文章提供了三個(gè)方法: 1.放棄mysql? 2.添加delete_token字段? 3.使用數(shù)據(jù)倉庫,評(píng)論區(qū)機(jī)智網(wǎng)友還提出了方法2的改進(jìn): 方法2.5。

方法2,即為數(shù)據(jù)庫添加新的一列delete_token,當(dāng)某一條記錄需要?jiǎng)h除時(shí),將該字段設(shè)置為一個(gè)UUID,將name、delete_token設(shè)置為唯一鍵,這樣當(dāng)is_delete=0時(shí),delete_token保持一個(gè)默認(rèn)值,能夠有效地限制name唯一,當(dāng)記錄被刪除時(shí),由于delete_token是一個(gè)唯一的UUID,便能保證刪除的記錄不會(huì)被唯一約束束縛。但正如該文章的博主所說,UUID會(huì)占用很大的空間,所以不推薦使用。評(píng)論網(wǎng)友針對(duì)該問題提出優(yōu)化對(duì)策:方法2.5:將刪除記錄的delete_token設(shè)置為該記錄的id。

個(gè)人認(rèn)為,索引太大只是其中一個(gè)弊端,該方法還會(huì)面臨一個(gè)很棘手的問題:當(dāng)需要批量刪除時(shí),需要對(duì)每一條記錄進(jìn)行逐行刪除。例如該表還有一個(gè)字段叫age,現(xiàn)在需要?jiǎng)h除age > 18的記錄,共有50條,在業(yè)務(wù)中,由于需要為每條的delete_token字段插入一個(gè)UUID所以需要將其拆分為50條更新操作來進(jìn)行。這樣的代價(jià)顯然很難接受



我該怎么辦?

每種辦法都有一定的應(yīng)用場景,既然強(qiáng)制要求使用邏輯刪除,就會(huì)面臨很多問題,在所難免。今天剛好突然想到一個(gè)不錯(cuò)的點(diǎn)子能解決邏輯刪除帶來的問題,若該方法已經(jīng)被提出,純屬巧合。

將刪除標(biāo)記設(shè)置默認(rèn)值(例如0),將唯一字段與刪除標(biāo)記添加唯一鍵約束。當(dāng)某一記錄需要?jiǎng)h除時(shí),將刪除標(biāo)記置為NULL。

由于NULL不會(huì)和其他字段有組合唯一鍵的效果,所以當(dāng)記錄被刪除時(shí)(刪除標(biāo)記被置為NULL時(shí)),解除了唯一鍵的約束。此外該方法能很好地解決批量刪除的問題(只要置為NULL就完事了),消耗的空間也并不多(1位 + 聯(lián)合索引)。

目前還沒發(fā)現(xiàn)這個(gè)辦法有什么奇怪的bug。如果有請(qǐng)不要吝嗇在評(píng)論區(qū)留言討論。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,279評(píng)論 2 89
  • MYSQL 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫概要 2 簡單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 MySQL基本操...
    Kingtester閱讀 8,050評(píng)論 5 115
  • 轉(zhuǎn) # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    呂品?閱讀 10,108評(píng)論 0 44
  • 1、2017倒計(jì)時(shí)8天。 2、今日金句:只有開放,才能專注。 3、每天想明白一個(gè)道理:付出不一定會(huì)有等值的回報(bào),但...
    向著美好奔跑閱讀 167評(píng)論 0 0
  • 領(lǐng)秀堂.總目錄 《“向巴別爾學(xué)寫作”專集》 1.跟巴別爾學(xué)寫作,《泅渡茲勃魯契河》憑啥是名篇 2.跟巴別爾學(xué)寫作,...
    領(lǐng)秀堂閱讀 575評(píng)論 0 1

友情鏈接更多精彩內(nèi)容