1. 程式人生 > 其它 >一般資料庫增量資料處理和資料倉庫增量資料處理的幾種策略

一般資料庫增量資料處理和資料倉庫增量資料處理的幾種策略

開篇介紹

通常在資料量較少的情況下,我們從一個數據源將全部資料載入到目標資料庫的時候可以採取的策略可以是:先將目標資料庫的資料全部清空掉,然後全部重新從資料來源載入進來。這是一個最簡單並且最直觀的並且不容易出錯的一種解決方案,但是在很多時候會帶來效能上的問題。

如果我們的資料來源來自於不同的業務系統,資料動輒百萬,千萬甚至億級計算。第一次需要全部載入,如果在第二次週期或者第三次週期的時候仍然全部載入的話,耗費了極大的物理和時間資源。有可能部分資料來源並未發生變化,而有的資料來源可能只是增加了少量的資料。

我們要考慮的問題是,對於已經存在目標資料庫中的資料都是歷史資料,對於資料來源中的資料我們只應該考慮新修改的記錄和新插入的記錄,只應該考慮這兩種資料。所以增量處理實質上就是處理變化的資料。

下面我們一起看看這些表,忽略從資料倉庫設計的角度,只考慮如何實現增量資料的檢測和抽取。

第一類 - 具有時間戳或者自增長列的絕對歷史資料表

這張表能夠代表一部分資料來源的特徵 - 絕對歷史事實資料。它指的是表中的資料是不可逆的,只有插入操作沒有刪除或者修改操作,表示在過去一段時間內完成的事實業務資料。比如這張表表示的某些產品的下載資訊,使用者什麼時候下載了產品就會在資料庫中記錄一條資料。

這種資料表一般會提供一列能夠記載這條記錄生成的歷史時間,或者說這個操作發生的時間,越早的操作時間越靠前,越晚的操作時間越靠後。

那麼對於這類表的增量處理策略就是:

  1. 第一次載入動作完成之後,記錄一下最大的時間點,儲存到一個載入記錄表中。
  2. 從第二次載入開始先比較上次操作儲存的最後/最大的時間點,只加載這個時間點以後的資料。
  3. 當載入過程全部成功完成之後再更新載入記錄表,更新這次最後的時間點。

另外,如果這類表有自增長列的話,那麼也可以使用自增長列來實現這個標識特徵。

第二類 - 有修改時間特徵的資料表

這類表中的資料一般屬於可以修改帶有維護性質的資料,比如像會員資訊表,建立會員的時候會生成一條記錄,會在 CreateDate 標記一下,並且在 UpdateDate 中儲存的也是 CreateDate 的值。當 CreateDate 和 UpdateDate 相同的時候說明這一條資料是插入操作,但是這個會員的資訊是可以被編輯和修改的,於是每次更新的同時也更新了 UpdateDate 時間戳。

假設上面的這幾條資料在第一次載入到目標資料庫後,源表新加入了一條會員記錄並同時修改了一條會員的資訊。

那麼像這種情況下增量資料處理的策略就可以是:

  1. 第一次載入動作完成以後,記錄一下最大的 UpdateDate 時間戳,儲存到一個載入記錄表中。(第一次是 2010-10-23)
  2. 在第二次載入資料的時候,用載入記錄表中的時間戳與源表裡的 UpdateDate 相比較,比時間戳大的說明是新新增的或者修改的資料。(大於 2010-10-23 的是第一條 Update 的資料和第四條新增的資料)
  3. 當整個載入過程成功之後,更新最大的 UpdateDate到記錄表中。(記錄表中將 2010-10-26 記錄下來)

但是要注意的是,不是每一個帶有修改時間特徵的資料表都會這麼設計,有可能在插入資料的時候只會放入 CreateDate 但是並不會寫入 UpdateDate。這樣的話,在每次載入的過程中可能就需要同時比較 CreateDate 和 UpdateDate 了。

第三類 - 關聯編輯資訊的無時間特徵資料表

這類表本身沒有任何可以標識的自增長 ID 或者時間戳,只保留基本資訊,所有的編輯操作等資訊專門有一張表來記錄。這樣的設計可以是為了單獨記載所有的編輯歷史資訊,但是同時又保留了主要資訊的獨立性,在查詢主表的時候查詢體積變小提供查詢效率。類似於這樣的設計可以參照第一類和第二類的設計方案,在這個示例中多出的就是要關聯 Member Audit History 表並進行時間戳或者自增長ID 的判斷。

第四類 - 無特徵資料表

很少有人這樣設計資料表,但是不代表不存在。我曾經碰到過一個檔案表,由於部分資料的敏感性不能直接訪問源資料庫,因此是由客戶從源資料庫將資料抽取出來儲存到一個文字檔案中。很遺憾的是,抽取出來的資料中只保留了建立時間,但是並沒有任何能夠標識修改行為的列。與客戶的溝通到最終客戶接受意見修改,到最終修改完成這中間是沒法停下來等客戶的,因此只能暫時採用另外的一種方法 - 基於唯一列的資料對比。

很簡單的概念 - 即每次載入資料來源中的資料時,基於主鍵或者唯一列到目標表中查詢是否存在,如果不存在就插入。如果存在就比較關鍵列資料是否相等,不相等就修改。

這種實現可以採用 SQL Merge 語句來完成 - 請參看-SQL Server - 使用 Merge 語句實現表資料之間的對比同步

或者通過 SSIS 中的 Lookup + Conditional Split 實現 - 請參看-SSIS 系列 - 資料倉庫中實現 Slowly Changing Dimension 緩慢漸變維度的三種方式

那麼對於前三類資料表,它們可以共同使用一個載入記錄表來記錄它們上一次的時間戳或者自增 ID。

對於 Table A -

SELECT 列1, 列2
FROM Table_A
WHERE ID > (SELECT LastSeqID FROM SourceLoadingAudit WHERE SourceTable = 'Table_A ')

對於 Table C -

SELECT 列1, 列2
FROM Table_C
WHERE UpdateDate > (SELECT LastModifiedDate FROM SourceLoadingAudit WHERE SourceTable = 'Table_C')

資料倉庫增量資料處理

資料倉庫增量資料處理一般發生在從 Source 到 Staging 的過程中,從 Staging 到DW 一般又分為維度 ETL 處理和事實 ETL 處理兩個部分。那麼實際上從 Source 到 Staging 的過程中,就已經有意識的對維度和事實進行了分類載入處理。通常情況下,作為維度的資料量較小,而作為業務事實資料量通常非常大。因此,著重要處理的是業務事實資料,要對這一部分資料採取合適的增量載入策略。

通常情況下,對資料倉庫從 Source 到 Staging 增量資料的處理可以按照這種方式:

  1. 對於具有維度性質的資料表可以在 Staging 中採取全解除安裝,全重新載入的模式。即每次載入資料的時候,先將 Staging 表資料清空掉,然後再重新從資料來源載入資料到 Staging 表中。
  2. 對於具有事實性質的資料表,需要考慮使用上面通用的集中增量資料處理的方案,選擇一個合適的方式來處理資料。保證在 Staging 事實中的資料相對於後面的 DW 資料庫來說就是新增的或者已修改過的資料。

但是也不排除大維度表的情況出現,即具有維度性質的資料表本身就非常龐大,像會員表有可能作為維度表,動輒百萬甚至千萬的資料。這種情況下,也可以考慮使用合適的增量資料載入策略來提高載入的效能。

至於從 Staging 到 DW 的這一過程,通常情況下包含了維度 SCD 過程和事實 Lookup 過程,這個在後面再陸續寫。關於緩慢漸變維度 Slowly Change Dimension 的相關理論文章可以檢視我的這篇部落格 -資料倉庫系列 - 緩慢漸變維度 (Slowly Changing Dimension) 常見的三種類型及原型設計

在 SSIS 中的實現可以參看我的這篇部落格 -SSIS 系列 - 資料倉庫中實現 Slowly Changing Dimension 緩慢漸變維度的三種方式

其它的載入策略

增量載入的處理策略不是一成不變的,採取哪一種載入策略跟資料來源的設計有很大的關係。良好的資料來源設計可能直接就給後續的增量處理提供了最直接的判斷依據,比如自增長列,時間日期戳等。還有的資料來源設計可能加入了觸發器,在資料新增,修改或者刪除的過程中就做出了有效的日誌記錄。或者加入了一些稽核表,在資料的增刪改過程中記錄並跟蹤了資料的操作細節,那麼這樣也是可以變通的採用上面的幾種增量載入策略來設計符合當前系統的流程。

如何在增量載入之上更進一步?

還有一個非常重要的問題就是:如何處理在增量載入過程中失敗的情況? 比如從 Source 到 Staging 的過程總共需要將資料寫入到10個不同的 Staging 表,但是在資料載入的過程中由於一些意外情況導致其中5個表載入失敗,其它5個表成功。由於考慮到效率問題,不想每次都重新載入,因此可以考慮採用以下兩種方式:

第一種方式 - SSIS Package 過程處理日誌和錯誤日誌模式

在每次 SSIS Package 執行的時候,寫入一條記錄到 ProcessLog 中,ExecutionStatus = 0 表示開始。執行成功的時候,更新 ExecutionStatus = 1 表示成功。執行失敗的時候,更新 ExecutionStatus = -1 同時在 Event Handlers 中記錄一條 Error Log 來記錄一些錯誤資訊。

下面這張表反映了在 ProcessLogID = 372 這一批次增量載入的 Audit 資訊表,當然甚至可以新增載入的條數等等資訊。Process Log ID = 372 的在 Process Log 表中反映出來的是一次成功的執行。

第二次執行的時候就會去檢查是否執行失敗的 Process Log ,如果沒有的話就根據 LastSegID 或者 LastModifiedDate 完成增量載入。

第三次執行的時候,發現 Audit 表中第二次有兩條沒有執行成功,因此只會對上次沒有成功的兩個表再次載入資料。

第二種方式 - SSIS Package 中的檢查點

具體內容可以參看 -SSIS 系列 - 通過設定 CheckPoints 檢查點來增強 SSIS Package 流程的重用性

通過這兩種方式,可以使我們的資料載入流程更加合理一些。通過增量資料的載入模式減少了一部分不必要的資料載入提升了效能,那麼在這個基礎之上通過日誌和檢查點模式在增量模式之上提高了載入過程的可重用性。已經載入過的,不再重複載入。載入失敗了的,重新載入,這樣對包的效能和健壯性又是一種提升。

不足之處就是第二次載入之後,由於有兩個表載入成功,另外兩張表載入失敗。因此等失敗的表重新載入之時資料來源可能已經發生變化,這樣造成成功與失敗的表面對的資料來源有所不一致,這一點在設計階段需要考慮,這種變化是否在允許的範圍內。

總結

增量資料載入的策略與資料來源有莫大的關係,也與實際需求有莫大關係,因此在設計增量資料載入的過程中需要圍繞實際需求以及資料來源能夠提供的增量變化特徵仔細思考,甚至反覆測試來達到載入機制的穩定和可靠性。

轉自https://www.cnblogs.com/biwork/archive/2013/11/27/3446236.html

藍天和白雲是標配。