马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
<hr> 拉链表概述
迟钝厘革维
通常我们用一张维度表来维护维度信息,比如用户手机号码信息。然而随着时间的厘革,某些用户信息会发生改变,这就是所谓的迟钝厘革维。必要留意的是,这里的迟钝厘革是相对毕竟表而言的,毕竟表的厘革速率要快得多。
针对迟钝厘革维标题,通常有以下几种处理处罚方式:
1)仅保存每个用户最新的一条维度信息
这种方法比力简朴粗暴,维度只思量最新就行,包管了维度值的唯一性。但缺点是无法查察汗青信息,在必要回溯查察数据的场景就不实用了,大概必要去原始数据查询,及其不方便。
2)仅保存每个用户最初的一条维度信息
这种就相当于一次填写,终身不允许修改,那么在现实关联数据时,很大概获取的是无效的维度信息。比如某个用户的手机号以及变了,但是维度表中仍然保存最初的手机号,这就导致数据关联结果是错误的。而且对于用户来说,一旦手残录入错误就无法再更改,用户的体验也是不好的。
3)用新增行的方式在维度表中同时保存全部厘革的维度信息
这种方式实在跟拉链表很靠近了,就是用户每改一次信息,就在维度表中新增一行,只不外这里的汗青数据和新增数据怎样区分,以及他们的有用时间范围怎样区分,就是必要偏重思量的标题了。
4)用新增列的方式在维度表中同时保存全部厘革的维度信息
这个方式的上风就是维度表的行数可以稳定,只必要新增列,但是缺点也很显着,新增列意味着表结构会不绝厘革,而且也没有办法确定到底要新增几列。
拉链表界说
拉链表就是记载一个事物从开始到当前状态的厘革过程的数据表,紧张是用于维度发生厘革的场景,也即我们常说的迟钝厘革维。
比如说我们用一张维度表记载用户的手机号码,但是随着时间推进,用户大概某一天会换手机号,这时我们的维度表就必要相应的更改,这时我们就可以用拉链表来举行记载,这就实现了保存汗青数据的同时,还能查询最新维度信息。可以说拉链表实在是办理迟钝厘革维的最佳方案了。
一个简朴的拉链体现比方下:
userid tel start_dt end_dt 01 111 20240101 20240601 01 222 20240602 99991231 02 333 20240101 99991231 每行记载都体现一个用户的属性值以及对应的日期有用范围,如果是最新的数据,则竣事日期是99991231。用户01的接洽方式发生过厘革,因此会有两条数据记载。
拉链表的实现
通例拉链表
汗青数据
现在有一批数据如下所示,体现用户的属性值以及传返来的日期和时间戳(单位s):
- with data1 as (
- select '01' as userid, 'ab' as addr, '20220101' as dt, 1641039513 as ts union all
- select '01' as userid, 'ab' as addr, '20220103' as dt, 1641211200 as ts union all
- select '01' as userid, 'cd' as addr, '20220108' as dt, 1641607200 as ts union all
- select '02' as userid, 'ab' as addr, '20220101' as dt, 1641039480 as ts union all
- select '02' as userid, 'bc' as addr, '20220104' as dt, 1641261600 as ts union all
- select '02' as userid, 'cd' as addr, '20220109' as dt, 1641639600 as ts union all
- select '03' as userid, 'ab' as addr, '20220101' as dt, 1641038400 as ts union all
- select '03' as userid, 'cd' as addr, '20220101' as dt, 1641002400 as ts union all
- select '03' as userid, 'ab' as addr, '20220107' as dt, 1641520800 as ts
- )
复制代码 汗青数据的处理处罚规则:
1)同一天仅保存最新一条数据
- select userid, addr, dt, ts
- from (
- select
- userid, addr, dt, ts
- row_number() over (partition by userid, dt order by ts desc) rn
- from data1
- ) ta
- where rn = 1;
复制代码 2)获取每个用户每个属性最早的一条数据
- with data2 as (
- select userid, addr, dt, ts
- from (
- select
- userid, addr, dt, ts,
- row_number() over (partition by userid, dt order by ts desc) rn
- from data1
- ) ta
- where rn = 1
- )
- select userid
复制代码 |