拉链表的介绍和使用

#博学谷IT学习技术支持#

1.拉链表的介绍

在数仓建模中,一般有渐变维度问题,不同的时间段有不同的状态,这就叫渐变维度问题。比如用户2021年在北京工作,2022年之后在上海工作,他的属性工作地发生的改变。
维度数据发生变化,如何处理发生变化的数据呢?
可以在表中添加两个字段start_time和end_time来标记这个属性的时间范围,如下表。

user_iduser_namework_areastart_timeend_time
100zhangsanbeijing2021-01-012021-12-31
100zhangsanshanghai2022-01-019999-12-31

其中9999-12-31表示目前最新的状态。一般拉链表用在dwd层(Data Warehouse Detail),数据来源于ods层(Operational Data Store)。

2.拉链表的使用

拉链表主要用在dwd层,用来及时记录每个事务状态的。加入ods层数据发生的新增或者更新,相应的dwd层的数据也会改变。拉链表数据生成的思路是:ods更新或者新增的数据 + union +dwd拉链表历史数据(要更改历史数据中状态发生改变的字段)。
方法有两种: 窗口函数和union。
准备数据:ods层的新增数据和dwd层连链表的历史数据
dwd层连链表的历史数据
dwd层连链表的历史数据
dwd层连链表的历史数据查询sql:

select
    userid,
    phone,
    nick,
    gender,
    addr,
    starttime,
    endtime
from yp_dwd.dw_zipper

ods层的新增数据
ods层的新增数据
ods层的新增数据查询sql:

select
    userid,
    phone,
    nick,
    gender,
    addr,
    starttime,
    endtime
from  yp_ods.ods_zipper_update

方式一: union

--:合并拉链表与增量表(tmp_zipper为新建的临时表,建表语句和拉链表一样)
insert overwrite table tmp_zipper
select
    userid,
    phone,
    nick,
    gender,
    addr,
    starttime,
    endtime
from ods_zipper_update
union all
--查询原来拉链表的所有数据,并将这次需要更新的数据的endTime更改为更新值的startTime
select
    a.userid,
    a.phone,
    a.nick,
    a.gender,
    a.addr,
    a.starttime,
    --如果这条数据没有更新或者这条数据不是要更改的数据,就保留原来的值,否则就改为新数据的开始时间-1
    if(b.userid is null or a.endtime < '9999-12-31', a.endtime , date_sub(b.starttime,1)) as endtime
from dw_zipper a  left join ods_zipper_update b
                            on a.userid = b.userid ;

查询结果
union方式的合并结果
结果显示userid=008的用户用两条记录,一条是addr=gz的历史记录,其中endtime=2021-01-01,一条是addr=gz的最新状态,其中endtime=9999-12-31。userid=011和userid=012是新增的记录。
方式二:窗口函数

select userid,
       phone,
       nick,
       gender,
       addr,
       starttime,
       if(lead_val is not null, date_sub(lead_val, 1), '9999-12-31') endtime
from (select *,
             lead(starttime, 1) over (partition by userid order by starttime) as lead_val
      from (
               select *
               from yp_dwd.dw_zipper
               union all
               select *
               from yp_ods.ods_zipper_update
           ) t) tt;

查询结果:
窗口函数的查询结果
查出来的结果和union方式一样。userid=008两条数据,一条addr=gz的历史记录(endtime=2021-01-01),一条addr=sh的最新数据(endtime=9999-12-31)。user=011和userid=012是新增的记录。

说明:一般会在dwd层建立拉链表的临时表,把合并的数据先放在临时表中,确定数据正确的在覆盖原来的拉链表。如果临时表中的数据有误且已经覆盖原来拉链表数据后,按照下节思路恢复历史拉链表的数据。

3.拉链表数据的恢复

ods的数据一般会按照日期分区存储,只要把当前日期之前的ods层的数据重新导入覆盖dwd层的历史拉链表数据即可。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值