数据库设计原则:应该使用软删除吗?
在數(shù)據(jù)庫設(shè)計中,當(dāng)刪除一條記錄的時候,是加一個標(biāo)記位還是直接刪除這一行?
物理刪除:真刪除,數(shù)據(jù)消失。
邏輯刪除:假刪除,數(shù)據(jù)存在,只是用一個字段來標(biāo)記該條數(shù)據(jù)“已刪除”。
參考了一些網(wǎng)絡(luò)上的討論如下:
關(guān)于soft delete的好處,justjavac的介紹很棒。
不過是否應(yīng)該使用soft delete,還是需要慎重考慮。
在關(guān)系型數(shù)據(jù)庫中,軟刪除(soft delete)主要影響的是write的效率,而不是read,所以在這種情況下,考慮采用soft delete的可行性的時候,也要考慮你的table/database面對的是否是write intensive的需求。另外,采用soft delete,一般是為了可能的恢復(fù),為了audit,為了保存歷史數(shù)據(jù)等等目的。那么為了某個或者某些數(shù)據(jù),是否soft delete真的是最好的處理方式呢?比如為了log的auditing,而對log采用soft delete,或許就有一些小題大做了。
而對于NoSQL數(shù)據(jù)庫,軟刪除通常來講是很容易接收的。尤其是Key-Value的NoSQL數(shù)據(jù)庫,比如Amazon的Dynamo DB和Riak等等,實現(xiàn)原理是hash table,所以就算有大量的soft delete數(shù)據(jù),也不會對性能造成巨大的影響。而對于其他類型的NoSQL數(shù)據(jù)庫,Document-based(比如CouchDB)或者Column-based(比如hbase)等等,data integrity重要性也是遠遠超過采用soft delete帶來的性能下降的。
小數(shù)據(jù)無所謂,看需求了
數(shù)據(jù)量大,最好另建一表保存刪除數(shù)據(jù)
刪除的很少用
根據(jù)需求而定,以后基本不用的數(shù)據(jù)完全可以刪除(可以采取緩沖處理,先標(biāo)記,后在系統(tǒng)不忙時刪除)節(jié)省空間,減少無用檢索;另一種情況,數(shù)據(jù)以后可能被重復(fù)利用,則打上標(biāo)記,空閑時移到歷史庫。
關(guān)系數(shù)據(jù)庫用來記錄當(dāng)前的客觀事實,增、刪、改,對應(yīng)事實的改變。
有一種類型的表稱為“history table”(或"audit table"),他們是專門用來記錄歷史數(shù)據(jù)的。通過trigger或存儲過程實現(xiàn)。他們的功能跟其他表不同,他們記錄的是對數(shù)據(jù)庫的操作,不是業(yè)務(wù)范圍的事實。history table通常數(shù)據(jù)量會隨時間越來越大,它們沒有刪、改,只有增、查(少量的查),而current table中的數(shù)據(jù)量相對較小,正好滿足業(yè)務(wù)需要(增、刪、改、查)。
打標(biāo)記好,萬一是某人發(fā)布了敏感言論然后刪除,那么警察叔叔查水表的難度肯定比用delete刪除的難度小的多。
數(shù)據(jù)庫設(shè)計原則–不要刪除數(shù)據(jù)
摘自Segment的問題回復(fù),個人認(rèn)為是對數(shù)據(jù)庫中刪除操作最好的詮釋,大部分情況下我們是濫用刪除或刪除標(biāo)記,真實情況中大部分情況我們只需修改記錄的狀態(tài)即可。因此在做數(shù)據(jù)庫設(shè)計中,我們決定使用刪除或刪除標(biāo)記的時候,我們需要再思考一次:在業(yè)務(wù)上,這真的是刪除操作嗎?
Udi Dahan 強烈建議完全避免數(shù)據(jù)刪除。
所謂軟刪除主張在表中增加一個 IsDeleted 列以保持?jǐn)?shù)據(jù)完整。如果某一行設(shè)置了IsDeleted標(biāo)志列,那么這一行就被認(rèn)為是已刪除的。Ayende 覺得這種方法“簡單、容易理解、容易實現(xiàn)、容易溝通”,但“往往是錯的”。問題在于:
刪除一行或一個實體幾乎總不是簡單的事件。它不僅影響模型中的數(shù)據(jù),還會影響模型的外觀。所以我們才要有外鍵去確保不會出現(xiàn)“訂單行”沒有對應(yīng)的父“訂單”的情況。而這個例子只能算是最簡單的情況。……
當(dāng)采用軟刪除的時候,不管我們是否情愿,都很容易出現(xiàn)數(shù)據(jù)受損,比如誰都不在意的一個小調(diào)整,就可能使“客戶”的“最新訂單”指向一條已經(jīng)軟刪除的訂單。
如果開發(fā)者接到的要求就是從數(shù)據(jù)庫中刪除數(shù)據(jù),要是不建議用軟刪除,那就只能硬刪除了。為了保證數(shù)據(jù)一致性,開發(fā)者除了刪除直接有關(guān)的數(shù)據(jù)行,還應(yīng)該級聯(lián)地刪除相關(guān)數(shù)據(jù)。可Udi
Dahan提醒讀者注意,真實的世界并不是級聯(lián)的:
假設(shè)市場部決定從商品目錄中刪除一樣商品,那是不是說所有包含了該商品的舊訂單都要一并消失?再級聯(lián)下去,這些訂單對應(yīng)的所有發(fā)票是不是也該刪除?這么一步步刪下去,我們公司的損益報表是不是應(yīng)該重做了?
沒天理了。
問題似乎出在對“刪除”這詞的解讀上。Dahan 給出了這樣的例子:
我說的“刪除”其實是指這產(chǎn)品“停售”了。我們以后不再賣這種產(chǎn)品,清掉庫存以后不再進貨。以后顧客搜索商品或者翻閱目錄的時候不會再看見這種商品,但管倉庫的人暫時還得繼續(xù)管理它們。“刪除”是個貪方便的說法。
他接著舉了一些站在用戶角度的正確解讀:
訂單不是被刪除的,是被“取消”的。訂單取消得太晚,還會產(chǎn)生花費。
員工不是被刪除的,是被“解雇”的(也可能是退休了)。還有相應(yīng)的補償金要處理。
職位不是被刪除的,是被“填補”的(或者招聘申請被撤回)。
在上面這些例子中,我們的著眼點應(yīng)該放在用戶希望完成的任務(wù)上,而非發(fā)生在某個實體身上的技術(shù)動作。幾乎在所有的情況下,需要考慮的實體總不止一個。
為了代替 IsDeleted 標(biāo)志,Dahan 建議用一個代表相關(guān)數(shù)據(jù)狀態(tài)的字段:有效、停用、取消、棄置等等。用戶可以借助這樣一個狀態(tài)字段回顧過去的數(shù)據(jù),作為決策的依據(jù)。
刪除數(shù)據(jù)除了破壞數(shù)據(jù)一致性,還有其它負面的后果。Dahan建議把所有數(shù)據(jù)都留在數(shù)據(jù)庫里:“別刪除。就是別刪除。”
—— 《NoSQL數(shù)據(jù)庫筆談》
總結(jié)
以上是生活随笔為你收集整理的数据库设计原则:应该使用软删除吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【jQuery】使用id选择器,找出外层
- 下一篇: 【Vue】Vue入门 -(本地篇+网络篇