數(shù)據(jù)倉(cāng)庫(kù)緩慢變化維度SCD?你想知道的都在這里
點(diǎn)擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)”


大家知道平時(shí)我對(duì)SQL Boy & Girl 有很深的成見,原因在于數(shù)據(jù)倉(cāng)庫(kù)本身博大精深,但是很多開發(fā)人員在用數(shù)據(jù)分析師的角色要求自己的開發(fā)能力。就像王者榮耀你本身是個(gè)刺客,輸出連個(gè)肉坦都比不過(guò),怎么好講自己是個(gè)刺客呢?
言歸正傳,今天我們要講的是數(shù)據(jù)倉(cāng)庫(kù)中的緩慢變化維度(SCD)。
緩慢變化維度 SCD
Slowly Changing Dimensions are dimensions that have data that slowly changes. 意思就是說(shuō)數(shù)據(jù)會(huì)發(fā)生緩慢變化的維度就叫”緩慢變化維”。
舉個(gè)例子,假設(shè)我們有一張我們公司的銷售員維度表如下,記錄了每個(gè)銷售員的一些基本信息,那么隨著時(shí)間的變化銷售員可能會(huì)在各省公司間調(diào)崗,如將周杰倫調(diào)入北京分公司,針對(duì)這種變化,業(yè)務(wù)系統(tǒng)會(huì)直接將業(yè)務(wù)數(shù)據(jù)庫(kù)中周杰倫的地址直接update為北京,而不會(huì)考慮歷史變化,不過(guò)在數(shù)據(jù)倉(cāng)庫(kù)中由于有時(shí)我們需要進(jìn)行歷史變化分析,或者防止銷售數(shù)據(jù)記錄錯(cuò)誤,所以需要對(duì)這種變化進(jìn)行相應(yīng)的處理。
很顯然在業(yè)務(wù)數(shù)據(jù)庫(kù)中數(shù)據(jù)的變化是非常自然和正常的,比如顧客的聯(lián)系方式,手機(jī)號(hào)碼等信息可能隨著顧客的所在地的更改發(fā)生變化,比如商品的價(jià)格在不同時(shí)期有上漲和下降的變化。那么在業(yè)務(wù)數(shù)據(jù)庫(kù)中,很自然的就會(huì)修改并馬上反映到實(shí)際業(yè)務(wù)當(dāng)中去。但是在數(shù)據(jù)倉(cāng)庫(kù)中,其數(shù)據(jù)主要的特征一是靜態(tài)歷史數(shù)據(jù),二是少改變不刪除,三是定期增長(zhǎng),其作用主要用來(lái)數(shù)據(jù)分析。因此分析的過(guò)程中對(duì)歷史數(shù)據(jù)就提出了要求,有一些數(shù)據(jù)是需要能夠反映出在周期內(nèi)的變化歷史,有一些數(shù)據(jù)不需要,那么這些數(shù)據(jù)應(yīng)該如何來(lái)控制。
處理緩慢變化維度是Kimball數(shù)倉(cāng)體系中永恒的話題,因?yàn)閿?shù)據(jù)倉(cāng)庫(kù)的本質(zhì),以及維度表在維度建模中的基礎(chǔ)作用,我們幾乎總是要跟蹤維度的變更(change tracking),以保留歷史,并提供準(zhǔn)確的查詢和分析結(jié)果。在《The Data Warehouse Toolkit, 3rd Edition》一書的第5章,Kimball提出了多種緩慢變化維度的類型和處理方法,其中前五種是原生的,后面的方法都是混合方法(hybrid techniques),因此下面來(lái)看看前五種,即Type 0~Type 4。
Type0 保留原始值
某一個(gè)屬性值絕不會(huì)變化。事實(shí)表始終按照該原始值進(jìn)行分組。比如在用戶維度表中,用戶注冊(cè)時(shí)使用的原始用戶名(original_user_name)。如果它發(fā)生變化,那么變化后的值是無(wú)效的,會(huì)被拋棄,始終按照用戶第一次填寫的數(shù)據(jù)為準(zhǔn)。很明顯這種方式是不推薦的。
Type1 覆蓋更新
與業(yè)務(wù)數(shù)據(jù)保持一致,同樣為直接update。這樣就難以記錄歷史變化,例如如果周杰倫于15年7月調(diào)入北京,那么我們想要知道北京銷售員在15年的銷售數(shù)據(jù)時(shí),就會(huì)將周杰倫的業(yè)績(jī)算入北京分公司下,實(shí)際上周杰倫7月份以前的銷售數(shù)據(jù)均應(yīng)算在臺(tái)北,所以為了避免這樣的問(wèn)題就有了TYPE2的處理方式。
書中給出的例子:

Type2 增加新的列
數(shù)據(jù)倉(cāng)庫(kù)系統(tǒng)的目標(biāo)之一是正確地表示歷史記錄。我們?cè)谏a(chǎn)環(huán)境中的基于Hive的數(shù)倉(cāng)建設(shè)過(guò)程中,拉鏈表就是直接的體現(xiàn)。
這種類型在維度表中添加兩個(gè)輔助列:該行的有效日期(effective date)和過(guò)期日期(expiration date),分別指示該行從哪個(gè)時(shí)間點(diǎn)開始生效,以及在哪個(gè)時(shí)間點(diǎn)過(guò)后會(huì)變?yōu)闊o(wú)效。每當(dāng)一個(gè)或多個(gè)維度發(fā)生更改時(shí),就創(chuàng)建一個(gè)新的行,新行包含有修改后的維度值,而舊行包含有修改前的維度值,且舊行的過(guò)期日期也會(huì)同步修改。書中的例子如下:

在上圖中,當(dāng)前有效列(current列)的過(guò)期日期會(huì)被記錄為9999-12-31。當(dāng)Department Name維度變化時(shí),舊有的Product Key為12345的行的過(guò)期日期被更新為修改日期,并且新建了一個(gè)Key為25984的行,包含新的數(shù)據(jù)。
需要注意的是,這里的Product Key是所謂代理鍵(surrogate key),即不表示具體業(yè)務(wù)含義,而只是代表表內(nèi)數(shù)據(jù)行的唯一ID。在處理SCD時(shí),代理鍵可以直接用來(lái)區(qū)分同一自然鍵(natural key)的數(shù)據(jù)的新舊版本。上圖中的SKU就是自然鍵。
這種類型的SCD處理方式能夠非常有效且精確地保留歷史與反映變更,但缺點(diǎn)是會(huì)造成數(shù)據(jù)的膨脹,因?yàn)榧词怪挥幸粋€(gè)維度變化,也要?jiǎng)?chuàng)建新行。
Type3 新增屬性列
用不同的字段來(lái)保存不同的值,就是在表中增加一個(gè)字段,這個(gè)字段用來(lái)保存變化后的當(dāng)前值,而原來(lái)的值則被稱為變化前的值。我們舉個(gè)很簡(jiǎn)單的例子,例如我們?cè)谟脩舯碇械挠脩糇≈愤@一列會(huì)變化,那么我們可以通過(guò)新增一個(gè)列來(lái)表示曾經(jīng)的地址:
原來(lái)的表:

現(xiàn)在我們新增一列pre_location來(lái)表示用戶的上一個(gè)住址:

這么做雖然解決上面的數(shù)據(jù)膨脹的問(wèn)題,但是如果很多個(gè)列都會(huì)變化,那么我們要新增很多系列,顯然這是不合理的。另外,這種做法只能保留上一次的數(shù)據(jù),那么更久遠(yuǎn)的變化就丟失了。
Type4 新增維度表
如果我們的表規(guī)模非常大,數(shù)據(jù)量千萬(wàn)以上,大量的列變化非常頻繁,那么這時(shí)候就不能用上面的辦法來(lái)支撐了,我們需要將那些快速變化的維度從原來(lái)的大維度表中拆分出來(lái)單獨(dú)處理,是為微維度(mini-dimension)。
我們用書中的內(nèi)容舉例,如果顧客維度中有一部分人口統(tǒng)計(jì)學(xué)(demographic)維度是RCD,就將它們拆成單獨(dú)的維度表:

最后給出一張《The Data Warehouse Toolkit, 3rd Edition》中的這幾種方式的比較圖:


版權(quán)聲明:
文章不錯(cuò)?點(diǎn)個(gè)【在看】吧!??




