2011-09-09 39 views
2

關於該主題有一些similarquestions,但它們並沒有真正幫助我。實施軟刪除,對性能和代碼影響最小

我想實現一個像StackOverflow一樣的軟刪除功能,其中的項目沒有真正刪除,但只是隱藏。我正在使用SQL數據庫。這裏有3個選項:

  • 添加一個is_deleted布爾字段。

    • 優點:簡單。
    • 缺點:沒有日期記錄。強制我在每個查詢中添加一個is_deleted = 0
  • 添加一個deleted_date日期字段。如果未刪除,則設置爲NULL

    • 優點:有約會。
    • 缺點:仍然混亂我的查詢。

對於上述兩種

  • 因爲有這些沒用的行還會影響性能。他們仍然需要維護索引。當獲取未刪除(大部分)的行時,deleted列上的索引也無濟於事。全表掃描是必要的。

另一種選擇是創建一個單獨的表來保存已刪除項目:查詢非刪除的行時,改進的性能:

  • 優勢。無需爲我的查詢添加條件在未刪除的行上。索引維護更簡單。
  • 缺點:複雜性:需要數據遷移刪除和刪除。需要新的表格。參照完整性很難處理。

有更好的選擇嗎?

+0

什麼RDBMS?可能有數據庫級別的技巧可以幫助您的努力 – billinkc

+0

我一直在尋找一個不可知論的解決方案,儘管Oracle,SQL Server和Postgres是首選 - 按此順序。 – Aillyn

回答

2

如果鍵是數字,我通過否定鍵來處理「軟刪除」。 (當然,不會用於身份密鑰)。根本不需要更改代碼,並且可以通過乘以-1輕鬆恢復記錄。

只是給予一些思考的另一種方法...如果密鑰是字母數字,您可以通過預先設置獨特的「標記」字符來做類似的事情。由於刪除的記錄將全部以該標記開始,因此最終會在索引中自行結束。

+0

創新理念,+1 – Aillyn

+0

你是什麼意思「你根本不需要改變你的代碼」?你不需要檢查鑰匙的標誌嗎? – Fowl

+0

也許更好的評論是,你根本不需要改變你的數據庫表結構。對不起,任何混淆 – Sparky

2

在我看來,考慮縮放和最終表/數據庫大小時,最好的方法是你的第三選項 - 一個單獨的表刪除項目。這樣的表最終可以移動到不同的數據庫以支持縮放。

我相信你列出了三個最常見的選項。正如你所看到的,每個都有優點和缺點。就我個人而言,我喜歡考慮更長遠的觀點。

2

我個人會基於我預測您的用戶希望訪問刪除的數據或「恢復」刪除的數據的頻率。

如果經常出現,那麼我會去一個「Date_Deleted」字段,並在代碼中將一個計算的「IsDeleted」放入我的poco中。

如果它從來沒有(或幾乎從不),那麼歷史表或刪除的表格對您所解釋的好處很有好處。

我個人幾乎從不使用刪除的表格(並選擇isDeleted或date_deleted),因爲這可能會引用參考文獻的完整性。你有A - > B,你從B數據庫中刪除記錄...你現在必須管理參考完整性,因爲你的設計選擇。

0

假設我們創建一個名爲dead的字段來標記刪除的行。我們可以創建一個索引,其中字段dead爲false。 這樣,我們只使用提示使用索引來搜索未刪除的行。

0

我認爲你對選項的分析很好,但是你錯過了下面列出的幾個相關點。幾乎所有我見過的實現都使用某種刪除或版本控制字段,正如您在前兩個選項中所建議的那樣。

使用一個表,刪除標誌: 如果指標均首次包含已刪除的標誌字段和您的查詢的大多包含在那裏請將isDeleted =假型結構,那麼它確實解決您的性能問題和指標非常有效地排除刪除的行。類似的邏輯可以用於刪除日期選項。

使用兩個表 一般來說,你需要做出巨大變化介紹,因爲一些報道可能是指刪除的數據(如舊的銷售數字可能是指刪除銷售類)。人們可以通過創建一個視圖來解決這個問題,這個視圖是兩個表的聯合,只能讀取和寫入活動記錄表。