拉链表的使用场景
Posted 大树的困惑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拉链表的使用场景相关的知识,希望对你有一定的参考价值。
拉链表的使用场景
拉链表,在面对处理的数据量比较大的时候,可以经常听说到,其主要的核心在于通过设置两个字段作为数据是否有效性的开关(begin_date,end_date)
这样做的目的是保证在表的数据,在某一个时间区间内(时间粒度得统一,月,日,时,分…)有且仅有一条有效的数据
下面介绍一种使用场景
背景
表t_vip_bal_info 用于记录某商户的vip用户的账户余额,当余额有变动时才会有数据
且每天(时间粒度为天)最多仅有单条数据
用户每当有新的余额变动时,旧的余额相对于当前就没用了,所以只有最新的才有用
t_vip_bal_info
统计某一日期的vip当前余额情况
--想统计某一日期的vip当前余额情况其实很简单,只需要排个序取最新就可以了
SELECT VIPID, C_DATE, BAL FROM
(
SELECT VIPID,
C_DATE,
BAL,
row_number() over(partition by vipid order by c_date desc) rn
FROM t_vip_bal_info a
where c_date <= 20210201
) a1 where a1.rn=1 order by VIPID, C_DATE asc
--通过row_number() 根据用户进行分区,可以取到每个用户在某一天前最新的一天余额信息
便可以获得每个用户当前最新的余额信息
这种方法有个弊端,最开始的天数比较少,所以比较的数据量也不大,如果随着时间的推移,数据一直在增量,用户以千万级别的增长,会发现效率极低了
在遇到这种大数据量的处理情况的时候,你想取最新一天的每个用户的余额情况,就需要拿前面所有天数的数据进行分析排序取最新
这种情况使用拉链表的思路,可以很好的解决这种情况
create table tmp_t_vip_bal_info as (
SELECT VIPID,
C_DATE,
BAL,
lag(c_date,1,99991231) over(partition by vipid order by C_DATE DESC) INVAILDDATE
FROM t_vip_bal_info a
)
--提供了余额失效日期之后,这样就保证了同一用户在某一天内有且仅存在一条余额数据
--(c_date <= custom_date) and (INVAILDDATE > custom_date)
SELECT VIPID,
C_DATE,
BAL,
INVAILDDATE
FROM tmp_t_vip_bal_info
where c_date<=20210201 and INVAILDDATE > 20210201
这样的结果就不需要全表排序取最新,只需要根据时间进行区间判断就可以取出当前最新且有效的数据了
以上是关于拉链表的使用场景的主要内容,如果未能解决你的问题,请参考以下文章