1 缓慢变化维(SCD)
处理维度表的历史变化信息的问题称为处理缓慢变化维的问题,简称SCD(Slowly Changing Dimensions)问题。
处理缓慢变化维的方法有以下几种常见方式:
- 保留原值
- 直接覆盖
- 增加新属性列
- 快照表
- 拉链表
在从 OLTP 业务数据库向 DW 数据仓库抽取数据的过程中,特别是第一次导入之后的每一次增量抽取往往会遇到这样的问题:
业务数据库中的一些数据发生了更改,到底要不要将这些变化也反映到数据仓库中?在数据仓库中,哪些数据应该随之变化,哪些可以不用变化?
考虑到这些变化,在数据仓库中的维度表又应该如何设计以满足这些需要。
维度能够根据变化剧烈程度主要分为无变化维度、缓慢变化维度和剧烈变化维度。
例如一我的的相关信息,身份证号、姓名和性别等信息数据属于不变的部分,政治面貌和婚姻状态属于缓慢变化部分,
而教育经历、工作单位和竞赛经历等在某种程度上属于急剧变化字段.
但是在数据仓库中,其数据主要的特征一是静态历史数据,二是少改变不删除,三是定期增长,其作用主要用来数据分析。
因此分析的过程中对历史数据就提出了要求,有一些数据是需要能够反映出在周期内的变化历史,有一些数据缺不需要,那么这些数据应该如何来控制。
2 种类
2.1 缓慢渐变类型1
不记录历史数据,直接覆写到数仓中: 如用户A年龄由 21 变成 22, 始终是1条记录(用户A年龄记录发生更改)
2.2 缓慢渐变类型2
每一次出现变更,就要添加一行新的记录;
尽可能的维护来自业务系统中的历史数据,捕获历史数据的变化。用户A年龄由 21 变成 22, 变成2条(用户A)记录;
因为多次变更而演变为了多条数据,原始业务表中的ID将不再具有唯一性,此时需要引入代理主键(Surrogate Key,唯一标识数据仓库表记录的键)。其次,维度表中的每一条数据都需要添加时间标签标识生效日期和位置。
2.3 缓慢渐变类型3(添加历史列)
3型SCD是2型SCD的一种改良处理,把新增行改为了新增属性;
只维护更少的历史记录,只记录上一次的历史信息;
直接记录当前最新的值和上一次变化前的值,加一列记录变化前的值;
3型SCD常表现为”曾用名”、”曾用地址”、”之前的浏览商品” 之类的属性列。
3 实现
3.1 类型1
覆盖写入即可
insert overwrite table user -- 可以考虑置换为分区表select * from user_new;
3.2 类型2: 拉链表技术
处理思路主要分两步,首先是设置代理主键,然后基于代理主键添加一条新的数据,最后把原数据中的时间标识进行处理(也可不处理):
-- 代理主键的设置(假设原来的user表中未设置代理主键)create table user_test -- 创建一个带代理主键的表user_testselect dense_rank() over (partition by user_id) as agent_key, *from user;
-- 基于代理主键添加一条新的数据(假设原表自带时间字段)insert into user_testselect dense_rank() over (partition by user_id) as agent_key, *from user_testwhere user_id = 10001 and time = sysdate('yyyyMMdd',-1);
-- 修改原来表中此user_id的非最新数据所对应的日期为'9999-01-01'(也可不改)update user_testset time = '9999-01-01'where user_id = 10001 and time != sysdate('yyyyMMdd',-1);
查找最新的数据:
可以通过代理键找最大的(主键往往是自增的,最大的通常是最新的数据)
查找历史时间的数据:
3.3 实现类型3
-- 创建一个表用于添加新的属性列,也可在原表上使用alter处理create table user_testselect *, address as last_address -- 添加一个last_address列from user;
-- 将用户新的address更新到表中update table userset user.address = user_test.addressfrom user join user_test on user.user_id = user_test.user_idwhere user.user_id = 10001;
