2011-11-02 72 views
2

我們有一個很長的ETL過程,它將來自輸入文件的數據通過一系列表格進行流動。打開和關閉外鍵約束

我認爲向我們的表添加關係完整性的可能性不大,但我不希望我們的ETL過程在遇到違規時死掉。我也想要違反參照完整性的記錄仍然被加載。然而,最後,我想知道所有違反參照完整性的行爲。

方法1: 我可以將參照完整性關閉並編寫一個運行一堆存儲過程的SQL過程來識別違反關係完整性的記錄,但我真的很喜歡關係完整性在表上本身的想法,因爲我覺得這會將數據庫記錄在最佳位置 - 數據庫。

方法2: 我認爲我們應該在流程開始時刪除所有ref完整性,然後在最後添加它,而不是編寫一組自定義查詢來標識違規者。如果我們得到例外,我們知道存在違規行爲。我喜歡這種方法,但是可以像方法1那樣編寫一個SQL來只針對潛在的違規者添加的記錄,增加ref完整性可能會重新檢查整個表 - 這個表不斷增長。當ref完整性被重新打開時,數據的使用者可以確信數據是「好的」,而不需要再進行即時查詢。我喜歡那個......

有沒有第三種方法? 我看到T-SQL支持像

NOCHECK CONSTRAINT 
ON UPDATE NO ACTION 
ON INSERT NO ACTION 

命令,但我不知道他們是如何真正意圖使用。例如,

ALTER TABLE dbo.TableName NOCHECK約束FK01

是這個意圖關閉constrationmt檢查,當你有一個可靠的消息來源?我假設如果它關閉,然後以這種方式打開,設置chg僅適用於未來的操作。

你會用什麼最好的方法來讓一個進程完成到最後,並且仍然能夠識別出所有的關係完整性或者可能的關係完整性違規?

+0

我們有類似的情況,現有的客戶依靠一天到一天這可能會導致無效的數據,但並不影響他們的業務任務。我選擇了1,因爲我們可以在現場運行自定義驗證程序,並查看哪些數據已經失效,因此我們知道需要修復哪些數據(程序和數據),然後才能啓用我們要添加的完整性約束。 – WileCau

回答

1

1.我發現NO ACTION名稱有點誤導,因爲這意味着如果違反約束條件,DML將會失敗。一些RDMS,尤其是mysql,有一個更好的關鍵字 - RESTRICT這更具描述性。
2.您可以暫時禁用/啓用所有的約束與ALTER TABLE ... NOCHECK/CHECK CONSTRAINT ALL

0

我個人從不關閉FK限制。這是一個滑入地獄的開始。他們在那裏是有原因的。

我會把你的ETL分成N行批量包裝每個交易。如果由於違反FK而導致交易失敗,請記錄它並執行任何您的恢復要求。切勿將不良數據保留在內。