2011-10-19 32 views
8

這不是一個具體的問題,更多的是一般的疑惑。兩難困境:級聯刪除或加入刪除

如果您必須以1:M關係對多個表進行刪除,最好是使用級聯刪除來創建FK約束,或者在刪除語句中連接表。

我有一箇舊的項目,有相關表單獨的刪除語句,有些語句沒有執行,數據完整性受到影響。我必須在兩者之間作出決定,所以我想了一下,這會是一個更好的解決方案。

還有一個選項可用於創建存儲過程或事務。

所以我正在尋找意見或建議......?

回答

4

如果您的數據庫有適當的RI定義,那麼不應該有任何數據完整性受損的情況。你所有的相關表都應該有聲明性的RI,這意味着你不能刪除父母,同時它仍然有孩子。另外,如果你的代碼只是在某些時候只刪除了一些行,那麼這就是編碼差和測試不良。這些行爲應該是單一交易。你使用存儲過程的建議是解決這個問題的一個很好的方法,而且非常標準。

如前所述,級聯觸發器有刪除某些人不打算刪除的行的危險。考慮到有時人們可能會從應用程序之外的某個地方訪問您的數據,尤其是在修復數據問題時。當有人不小心嘗試刪除錯誤的父節點並獲得好的RI錯誤時。當他們不小心嘗試刪除錯誤的父母,並且它不僅刪除了那個父母,而且還刪除了另外5個表中的20個孩子,那很糟糕。

另外,級聯刪除非常隱蔽。如果開發人員爲父代編寫了刪除代碼,那麼他們應該知道他們必須使用刪除存儲過程來照顧孩子。開發人員沒有對代碼進行編碼,發現錯誤,修復代碼(或者意識到他並不真的想要完成所有的刪除操作)比開發人員進行刪除並擁有更多沒有人意識到,直到代碼生效之前它纔會殺死孩子。

海事組織,我更願意讓我的開發人員瞭解應用程序,而不是讓他們更容易對其不瞭解。

7

我想說使用級聯刪除更安全。如果你決定使用聯接,你必須記住每次從父表中刪除任何東西時使用它們;即使你有足夠的紀律去做,你也不能確定你的同事或將來支持你的軟件的人。此外,不止一次編碼有關表關係的知識違反了DRY原則。

如果您使用級聯刪除,但沒有人需要記住任何內容,並且根據需要始終刪除子行。

+0

完全。很好的答案和良好的表達。數據完整性一直沒有引起足夠的重視,通常會在幾年之後開始出現,通常會導致許多公司扼殺 - 由於很久以前關於數據收集的糟糕決策,他們無法進行創新和改變。 –

+0

由於在手動刪除數據時可能發生意外,似乎存在與級聯刪除相關的一些瑕疵。就我個人而言,我遇到了一些不好的經歷,但我仍然認爲,保持嚴格的數據完整性是一種更安全的方式。另一方面,我仍然嘗試避免使用級聯。 –

4

級聯刪除會導致很多問題,因此非常危險。我不會推薦使用它。首先,假設我需要刪除擁有數百萬個子記錄的記錄。您可以鎖定數據庫並使其無法使用數小時。我知道有很少的dbas會允許在他們的數據庫中使用級聯刪除。

接下來,如果您定義了FK,它對數據完整性沒有幫助。刪除子女檔案仍然存在將失敗這是一個的事情。如果客戶現有訂單,我希望客戶刪除失敗。無意中使用級聯刪除(通常以我的經驗),可能會導致刪除您真正不想刪除的內容。

0

同時使用!

「聯合」手動刪除通常更適合避免死鎖和其他爭用問題,因爲您可以將刪除分解爲更小的工作單元。如果您確實有爭議,那麼肯定會更容易找到衝突的原因。

如前所述,「刪除級聯」將絕對保證參照完整性。

因此,請同時使用 - 在連接的sqls中顯式刪除「children」以避免死鎖和性能問題。但留下「CASCADE DELETE」啓用可以捕獲任何你錯過的東西。由於在刪除父母時不應該有孩子離開,所以這不會讓你付出任何代價,除非你刪除了一個錯誤,在這種情況下,爲了維護你的參考完整性,費用是值得的。

+0

任何外鍵都保證參照完整性 –