拉链表

拉链,通俗来讲即打开和关闭数据,设计表的时候添加 start_date  和  end_date 两个字段,数据更新时,通过修改 END_DATE 来设置数据的有效时间。
数据的拉链表只存一份全量数据,其余都是增量数据,查询时使用 start_date  和  end_date 作为约束条件来筛选某日的数据快照。同时可以节省存储空间,记录历史变化。

哪些情况下使用拉链表

  1. 数据量比较大;
  2. 表中的部分字段会被更,如销售部门,产品的描述信息,订单的状态等等;
  3. 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某销售在历史某段时间内的归属部门,再比如,统计某一个用户在过去某段时间内,有更新过几次等;
  4. 变化的比例和频率不是很大,比如,总共有1000万的会员,每天新增和发生变化的有10万左右,如果对这边表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极大的浪费。

综上所述:引入"拉链历史表",既能满足反应数据的历史状态,又可以最大程度的节省存储。

--提取全量最新数据
drop table if exists tmp.tmp_zip_one;
create table tmp.tmp_zip_one as
select saler_id,saler_name,shop_id,shop_name
from table_name
where dt='20201015';

--备份之前数据状态,dim_zip为目标拉链维表,分区dp有两个,分别为active(当前)和his(历史)
drop table if exists tmp.tmp_zip_two;
create table tmp.tmp_zip_two as
select * from dimdb.dim_zip;

--更新active分区
insert overwrite table dimdb.dim_zip partition(dp='active')
-- 不变的
select 
	ta.saler_id,
	ta.saler_name,
	ta.shop_id,
	ta.shop_name,
	ta.start_date,
	ta.end_date
from tmp.tmp_zip_one ta
	join tmp.tmp_zip_two tb
	on ta.saler_id = tb.saler_id
	and tb.dp = 'active'
where ta.shop_id=tb.shop_id
union all
-- 新增的
select
	ta.saler_id,
	ta.saler_name,
	ta.shop_id,
	ta.shop_name,
	date_sub(current_date(), 1) as start_date,
	'9999-01-01' as end_date
from tmp.tmp_zip_one ta
	left join tmp.tmp_zip_two tb
	on ta.saler_id = tb.saler_id
	and tb.dp = 'active'
where tb.saler_id is null
union all
-- 改变的,改变后
select
	ta.saler_id,
	ta.saler_name,
	ta.shop_id,
	ta.shop_name,
	date_sub(current_date(), 1) as start_date,
	'9999-01-01' as end_date
from tmp.tmp_zip_one ta
	join tmp.tmp_zip_two tb
	on ta.saler_id = tb.saler_id
	and tb.dp = 'active'
where ta.shop_id!= tb.shop_id;


--更新历史分区
insert overwrite table dimdb.dim_zip partition(dp='his')
-- 改变的, 改变前
select
	tb.saler_id,
	tb.saler_name,
	tb.shop_id,
	tb.shop_name,
    tb.start_date,
	date_sub(current_date(), 2) as end_date
from tmp.tmp_zip_one ta
	join tmp.tmp_zip_two tb
	on ta.saler_id = tb.saler_id
	and tb.dp = 'active'
where ta.shop_id!= tb.shop_id
union all
-- 最新删除的
select
	tb.saler_name,
	tb.shop_id,
	tb.shop_name,
	tb.start_date,
	date_sub(current_date(), 2) as end_date
from tmp.tmp_zip_two tb
	left join tmp.tmp_zip_one ta
	on ta.saler_id = tb.saler_id
where tb.dp = 'active'
and ta.saler_id is null
union all
-- 之前删除、改变的
select
	tb.saler_name,
	tb.shop_id,
	tb.shop_name,
	tb.start_date,
	tb.end_date
from tmp.tmp_zip_two tb
where tb.dp = 'his';

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值