SCD缓慢变化维拉链表

                           SCD缓慢变化维拉链表SQL实现

1 缓慢变化维概述

SCD英文Slow Changing Dimensions(SCD 缓慢变化维),它是数据仓库建模过程中一个非常重要的概念。众所周知数据仓库是基于历史数据的,而历史数据的变化依赖于维度的定义,缓慢变化维就是用来跟踪和表现维度表变化的一种方法。

注: 1 当前代码演示环境是SQL Server,基于Merge语法,其它数据库类似。

      2 SCD缓慢变换维Kettle实现

 

常见有3中分别记作Type1、Type2、Type3。这里假如我们有用户维度表customer客户(cust_id用户编号、name姓名、age年龄),如果在某个时间将某个用户的age更新成40,我们看下三种维度处理的方法的情况。

  • Type1(不会记录维度里关键字段值的变化历史情况):

cust_id name age

1 张三 30

新的customer表为:

cust_id name age

1 张三 40

  • Type2:

针对1的情况则,这里假设更新时间是2020-10-21

cust_id name age start_date end_date is_current

1       张三  30 2020-10-10 2020-10-21 0

1       张三  40 2020-10-21 9999-10-21 1

  • Type3

直接记录当前最新的值和上一次变化前的值

cust_id name age pre_age

1       张三 30  40

综上所述不难发现type1和type2不能很好的记录维度的变化情况,type1没有,type3只能记录最新的一次变化。

 

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
       )
)

GO

ALTER 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 Src
    ON Dim.CustomerAlternateKey = Src.ID
WHEN NOT MATCHED BY TARGET
    THEN 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=1

    THEN 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 Src
    ON Dim.CustomerAlternateKey = Src.ID
       AND Dim.City = Src.City AND Dim.Occupation = Src.Occupation
       WHEN NOT MATCHED BY TARGET
       THEN 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表的变化,查看是否追踪到数据的历史变更信息。

猜你喜欢

转载自blog.csdn.net/shenliang1985/article/details/114079616
今日推荐