SCD缓慢变化维拉链表
? ? ? ? ? ? ? ? ? ? ? ? ? ?SCD緩慢變化維拉鏈表SQL實現
1 緩慢變化維概述
SCD英文Slow Changing Dimensions(緩慢變化維),它是數據倉庫建模過程中一個非常重要的概念。眾所周知數據倉庫是基于歷史數據的,而歷史數據的變化依賴于維度的定義,緩慢變化維就是用來跟蹤和表現維度表變化的一種方法。事實表往往在跟維度表關聯時需要“卡”住相應的時間節點,這就是SCD記錄歷史變化的作用。
注: 1 當前代碼演示環境是SQL Server,基于Merge語法,其它數據庫類似。
? ? ? 2 SCD緩慢變換維Kettle實現
? ? ? 3?Kettle轉換作業應用50個案例腳本?
數據倉庫里維度表的字段改變(變化)常見的有3種,分別記作Type1、Type2、Type3。這里假如我們有用戶維度表customer客戶(cust_id用戶編號、name姓名、jobtitle職位),如果在某個時間將某個用戶的職位由Dev更新成CTO,我們看下三種維度處理的方法的情況:
- Type1(不會記錄維度里關鍵字段值的變化歷史情況):
| cust_id | name | jobtitle |
| 1 | 張三 | Dev |
新的customer表為:
| cust_id | name | jobtitle |
| 1 | 張三 | CTO |
- Type2(記錄維度里關鍵字段每次的變化情況):
針對1的情況假設更新時間是2020-10-21,那么對應到客戶維度表里(這里end_date對應最新時一般設置為9999-12-31或者NULL),則有如下的軌跡:
| cust_id | name | jobtitle | start_date | end_date | is_current |
| 1 | 張三 | Dev | 2020-10-10 | 2020-10-21 | 0 |
| 1 | 張三 | CTO | 2020-10-21 | NULL | 1 |
- Type3(直接記錄當前最新的值和上一次變化前的值)
| cust_id | name | jobtitle | pre_jobtitle |
| 1 | 張三 | CTO | Dev |
綜上所述不難發現type1和type3不能很好的記錄維度的每次變化情況,type1沒有,type3只能記錄最新的一次變化,而type2會記錄每次變化(關注的字段需自定義)的情況。
注:一般來說事實表會存放維度表的ID,而事實表抽取(ETL)的過程中是通過維度表的start_date和end_date來確定事實表里度量(指標)的時間范圍(即維度表的對應時間)。
2 代碼與注釋
2.1 表結構與數據
-- step1 準備表和數據,當前運行在SQL Server里。-- 業務系統(OLTP)的客戶表 CREATE TABLE Customer(ID int IDENTITY(1,1) NOT NULL,FullName nvarchar(50) NULL,City nvarchar(50) NULL,Occupation nvarchar(50) NULL)-- 數據倉庫的(OLAP)的客戶維度表 CREATE TABLE DimCustomer(CustomerID int IDENTITY(1,1) NOT NULL,CustomerAlternateKey int NULL,FullName nvarchar(50) NULL,City nvarchar(50) NULL,Occupation nvarchar(50) NULL,StartDate datetime NULL,EndDate datetime NULL,IsCurrent bit NULL,PRIMARY KEY CLUSTERED(CustomerID ASC) )GOALTER TABLE DimCustomer ADD? DEFAULT ((1)) FOR IsCurrent INSERT INTO Customer(FullName,City,Occupation) SELECT 'BIWORK','Beijing','CEO' UNION ALL SELECT 'ZhangSan','Shanghai','Education' UNION ALL SELECT 'Lisi','Guangzhou','IT' UNION ALL SELECT 'Wangwu','Beijing','Finance'2.2 緩慢變換維代碼
-- step2 SCD 模塊 -- 1 修改狀態 MERGE INTO dbo.DimCustomer AS Dim USING dbo.Customer AS SrcON Dim.CustomerAlternateKey = Src.ID WHEN NOT MATCHED BY TARGETTHEN INSERT VALUES(Src.ID,Src.FullName,Src.City,Src.Occupation,GETDATE(),NULL,1) WHEN MATCHED AND (Dim.City <> Src.City OR Dim.Occupation <>? Src.Occupation) AND Dim.IsCurrent=1THEN UPDATE SET Dim.EndDate =CASE WHEN Dim.EndDate IS NULL THEN GETDATE() ELSE Dim.EndDate END,Dim.IsCurrent = 0;-- 2 修改數據 MERGE INTO dbo.DimCustomer AS Dim USING dbo.Customer AS SrcON Dim.CustomerAlternateKey = Src.IDAND Dim.City = Src.City AND Dim.Occupation = Src.OccupationWHEN NOT MATCHED BY TARGETTHEN INSERT VALUES(Src.ID,Src.FullName,Src.City,Src.Occupation,getDATE(),NULL,1);2.3? 修改數據驗證
-- Step3 驗證 -- 新插入一條 INSERT INTO Customer(FullName,City,Occupation) VALUES ('qinliu','Beijing','Finance')-- Case1: 執行如下更新后執行SCD模塊,這里的ID依賴于自增序列生成的序號UPDATE Customer SET Occupation = 'IT' WHERE ID = 6-- Case2: 執行如下更新后執行SCD模塊,這里的ID依賴于自增序列生成的序號 UPDATE Customer SET Occupation = 'Publisher',City = 'Hangzhou' WHERE ID = 6-- 每次修改后對照查看DimCustomer表的變化,查看是否追蹤到數據的歷史變更信息。以下為查詢示例: SELECT * FROm DimCustomer WHERE FullName='qinliu'總結
以上是生活随笔為你收集整理的SCD缓慢变化维拉链表的全部內容,希望文章能夠幫你解決所遇到的問題。