寫在前面

本篇先不討論Data Vault其本身,因爲不見得所有人都接受這個。但是裏邊有一些很不錯的東西跟主流的數據倉庫方法是有共同點的,所以這裏主要討論這些共同的方法,在筆者看來,無論是Kimball還是DV,這些方法都是很有用的。這個系列爲作者本人哥本哈士奇的個人理解和總結,可能會有理解上的偏差,也歡迎大家一起來討論。

哈希計算

常用的哈希計算,HASH KEY, HASH FULL, HASH DIF,這裏會有簡單的介紹。

關於如何做哈希計算,可以參考這個鏈接:

https://www.hansmichiels.com/2016/04/09/hash-diff-calculation-with-sql-server-datavault-series/

HASH KEY

哈希鍵,通常是根據業務鍵來生成的,比如車輛的唯一識別號,如果已知一個系統的業務鍵跟另外一個系統的業務鍵可能有重合,那麼可以考慮把RECORD SOURCE(後面會有介紹)也加進來參與計算。

在傳統的數據倉庫方法論裏,出於性能角度的考慮,會在維度加載的時候去維護一個維度鍵和代理鍵的映射表,生成一個數值作爲代理鍵,然後在維度表裏只保留這個數值。維度加載完畢之後,加載事實表的時候,遇到了這個維度鍵,先會去映射表裏查對應的代理鍵,然後在維度表裏也只會保留這個代理鍵。這樣可以確保事實表和維度表做JOIN時的性能。

同樣在Data Vault的最初1.0版本中,也是先建議先加載HUB表,然後有對應的映射表,最後保留代理鍵。

這種方法確保了查詢時的性能,但是有一個不好的地方就是維度表和事實表,或者HUB表對LINK和SAT表的加載順序就有了要求。所以在Data Vault版本2.0裏,沒有再沿用這種方法,而是採用HASH KEY的方式,這樣HUB,LINK和SAT三類表就可以同時加載。

是的,你會對這樣做同樣有性能上的疑慮,因爲生成的HASH KEY從數據表的底層組織上不是最優的,相比於用數值類型的代理鍵,由於數值類型是連續的,所以底層的數據保存也是連續的,HASH KEY的生成很明顯不是連續的,所以在數據的保存上不如數值類型的代理鍵效率好,會有頁分裂導致的性能問題。

這個問題Dan有一個討論在此:

http://roelantvos.com/blog/using-a-natural-business-key-the-end-of-hash-keys/

從我個人來理解,如果說其好的一面,雖然這樣會降低ETL加載的性能,但是這個方法使並行加載變得可行,而且避免了ETL過程中的key look up,所以總體來說對ETL的性能收益是正向的還是負面的,需要具體去看。

另外還有一種情況可以不使用哈希鍵,比如公民身份證號,這個是絕對不會重複的,還有比如車輛識別編碼等。

建議採用度:四星(五星滿星)

HASH DIF

這是一個很有用的列。其做計算的時候會根據除了業務鍵列之外的所有列,生成一個唯一串。其好處就是在於,當源端系統不能自己告訴你數據是否變化了的時候,通過這個方法就可以很容易的判斷。

比如一個表有20個列,爲了判斷新來的數據是否發生了變化,你是會去一列一列的對比呢,還是將這些列先計算成一個哈希值,然後只對這個哈希列去進行比對?很明顯後者更高效。

Dan提到過一點,對於有些數據平臺比如Teredata,其本身是自帶這個列的,所以不需要去自己生成這個列。所以我覺得Dan是從此借鑑過來的吧。

建議採用度:五星

RECORD SOURCE

記錄這個數據是從哪個數據來的。

在需要對大量的系統做整合的時候,這個列就很有用,比如在快消領域,標識一個產品的編碼到底是從產品系統中來的,還是從價格管理系統中來。

這裏我想強調的一點是,很多人都誤以爲這個字段是記錄數據怎麼來的,實際上不是,這個只記錄數據從哪裏來,通常都是源系統的名稱,而不是你期望的A+B這種信息。

它的作用也更在於如前面提到,當生成HASH KEY的時候,如果已知業務鍵在不同的系統間可能有重複,爲了能將他們整合到一起,需要用到RECCORD SOURCE來參與計算。

建議採用度:五星

LOAD DATE

數據加載時間,這個是指數據在第一次加載到數據倉庫的時間,而這個範圍要從STAGE層算起。

提及這個字段不得不說另外一個字段,LOAD END DATE,就是數據在哪次加載時消失或者被更改了。

按照SCD2的規則,如果是刪除的數據,會先把歷史記錄的LOAD END DATE更新,這樣這條記錄的時間線在數據倉庫中中止。如果是更新的數據,首先還是會去更新歷史數據的LOAD END DATE,然後會再新加一條更新後的記錄。

這樣根據這個記錄的生效開始時間和結束時間,就可以在時間線上看到一條數據的變更歷史線。

在很多我看到的Data Vault社區討論中,尤其是對於PSA的設計,都傾向於只插入,不更新歷史記錄的方法。也就是說,沒有LOAD END DATE。其中一個理由就是對於記錄的物理更新,在大量ETL數據操作的時候對性能影響會很大。

這樣做不會耽誤對歷史數據的變更追溯,因爲根據LOAD DATE,同樣能拉出一條時間線。只是需要配合CHANGE INDICATOR列,不然刪除的數據只靠LOAD DATE是無法辨識的。

建議採用度:五星

DATE EXPORT DATE

數據導出或者生成的時間。通常是針對無法直接連接到源數據庫的情況,比如源系統需要把數據導出來,或者通過中間的ESB或者webservice之類的接口。這個主要是爲了數據審計的目的,有時候對於數據問題的排查也很重要。

這個信息需要源系統端帶過來,不過確實很難指望所有的系統都能帶過來這個信息,所有可以考慮置空。

建議採用度:三星

CHANGE INDICATOR

數據變更的指示器。

很多源系統很難提供這個列,而且即使源系統提供了也不見得跟數據倉庫的加載週期一致,所以會在數據倉庫比對得出,這個時候LOAD_DTS和HASH KEY以及HASH DIFF就發揮了作用。

通常用I代表數據是第一次插入的,U代表數據這次加載是一個更新操作,D代表刪除操作。

建議採用度:五星

相關文章