DTS增量導出方案彙總

1.觸發器
    這是一個非常簡單直接的解決方案,我們只需要將DTS引擎駐留在比如windows服務中,該引擎通過數據庫的觸發器事件獲取源表數據更新的所有情況,即增量,然後相應的更新目的表。然而,由誰來創建觸發器了?
    我們DTS系統的任務是將數據從一個表遷移到另外一個表,它所擁有的權限是:
(1)讀取源表
(2)讀寫目的表
    我們沒有創建觸發器的權限,更別說接收觸發器的事件了。
    觸發器方案馬上被否決!

2.查詢數據庫的增量記錄
    觸發器方案被否決後,我們退而求其次,我們希望所有的數據庫都提供了某種機制,能讓我們查詢指定表的增量記錄。比如,我們給出一個時間段和指定表的名稱,調用數據庫的某個函數或存儲過程或擴展SQL命令,數據庫返回一個結果數據集,這個數據集中包含了指定的時間段內,指定表中有哪些數據是新添加的、哪些數據被刪除了、哪些數據是更新過的。如果能進行這樣的數據庫增量查詢,那麼增量導出也會比較簡單。
    爲此,我們尋找了相關的資料,主要針對Oracle和SqlServer,到現在爲止,還沒有發現其中的一個數據庫內置了類似的機制。其實,我們可以想想,數據庫當然可以實現這樣的機制,但是代價可能非常高昂。比如,數據庫要記錄“刪除增量”,如果對應的指定表沒有設置主鍵,數據庫該用什麼來唯一標誌被刪除的記錄了,可能的辦法是使用臨時表把被刪除的記錄完整的記錄下來,如果要完整的記錄下被刪除的記錄,那麼臨時表的大綱就需要與指定表的大綱完全相同。因此,數據庫需要爲每個表都建一個大綱完全相同的表來存儲這些增量記錄。隨時間流逝,無疑,這些臨時表中的數據會越來越多,那麼,誰來負責刪除這些臨時表中的增量記錄數據了?該刪除哪些增量記錄了?
    我們知道,大多數據庫都實現了增量備份的功能,如果增量備份不是採用主條記錄比對的話,可能就是使用了臨時表,這樣,增量備份的時刻就是數據庫清空臨時表的最佳時機。但是對於隨機的、可重複性的增量導出來說,還存在清空臨時表的時機嗎?也許你剛剛清空了臨時表的部分記錄,而我再一次類似的增量導出可能需要用到你剛清除的那些增量記錄。
    看來,我們希望所有的數據庫(不僅僅是Oracle和SqlServer)提供一種機制、自動爲我們記錄所有時間內每個表的增量是不太可能的。該方案被否決。

3.雙排序逐條記錄比對
    我們再一次退而求其次,採用最笨的逐條記錄比對的方法。最笨的方案中也可以用一些效率較高的技巧,我們首先考慮到的是雙排序逐條記錄比對。
    所謂雙排序,只的是對存在於源表中的記錄和目的表中的記錄都採用主鍵排序的方式,這樣通過主鍵值相同來識別匹配的記錄,然後再比對其餘的字段來判斷數據是否更新;如果源表中的某條記錄在目的表中沒有找到匹配,表明這條記錄是新增加的。
   如何判斷那條記錄是刪除的?通常的做法是採用反向遍歷,即從目標表中選取一條記錄,然後遍歷源表,如果沒有發現這條記錄,則表明發現了一個刪除增量。
    採用雙排序的方法,可以很快的識別刪除增量。我們分別爲已排序的源記錄和已排序的目標記錄設置一個指針,這個指針只能單步前進,然後將兩個指針指向的記錄拿出來進行主鍵值比較,如果發現相同,則說明發現了匹配,處理該條記錄,然後兩個指針各前進一步;如果源主鍵值較小,則說明該條記錄是新增加的;如果源主鍵值較大,則說明目的指針指向的當前記錄已經在源表中被刪除,這是一個刪除增量。
    這種方案似乎是可行的,雖然要逐條比對,但是效率也不會太低。
    可是,如果所操作的表採用的是聯合主鍵了(即,聯合主鍵中的任何一個鍵的數據都可能是重複的,但是將它們聯合起來,在表中卻又是唯一的)?我們仍然可以進行實現排序,記錄匹配也同樣可以進行,只不多前面我們通過主鍵值相等來進行匹配,這裏需要通過多個列的值全相等來進行匹配。
    我們再考慮複雜一點的情況,如果主鍵進行了分裂,或者參與了合併的情況了?經過排序後,主鍵的值是有序的,可是主鍵分裂的值(或者合併後的目標值)卻不一定是有序的。這樣就沒有辦法進行雙排序操作了。因爲當操作源數據中的任意一條記錄時,都可能需要遍歷目的表中的所有記錄。

4.單排序逐條記錄比對
    我們現在採用的方法是單排序逐條記錄比對,即只對源表記錄排序,然後逐條記錄處理。這樣效率要低得多,但是任務反而變得單純些。效率最低的地方體現在識別“刪除增量”,因爲要用到反向遍歷操作。我們希望找到更好的方法來替代它。

     在實際的實現中,你可能還會遇到一些困難,比如,我們的源表/目的表中的記錄非常多,所以不可能一次將它們讀入到內存中,我們需要分頁。標準的sql不支持分頁,針對不同的數據庫有不同的實現方式,特別是當複雜的排序(如聯合主鍵排序)摻雜在其中時,分頁操作更爲困難。再就是,對BLOB、CLOB、LOB數據的比對,是否要一個一個byte的進行比較來決定其是否爲“更新增量”了?
    另外,我們需要對增量導出做更細粒度的控制,比如可以讓其選擇在增量導出時能分別控制開啓或關閉“Add增量”、“Update增量”、“Delete增量”的導出。如果我們確信不需要“Delete增量”導出,那麼就可以節省大量的導出執行時間。

5.利用SQLServer提供的DTS工具
   在源庫與目標庫相關的表上加時間戳並創建索引,然後用DTS按時間戳抽取 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章