本文大量内容系转载自以下文章,有删改,并参考其他文档资料加入了一些内容:
增量表:新增数据,增量数据是上次导出之后的新数据。比如说,从24号到25号新增了那些数据,改变了哪些数据,这些都会存储在增量表的25号分区里面。
加工逻辑:
insert overwrite table wedw_dwd.test_user_info_di PARTITION(date_id='2020-04-07')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
from wedw_dwd.test_user_info_di a
left join wedw_ods.test_user_info_20200407 b
on b.user_id=a.user_id
where a.date_id = '2020-04-06'
and b.user_id is null;
insert into table wedw_dwd.test_user_info_di PARTITION(date_id='2020-04-07')
select
coalesce(user_id'-99') as user_id
,coalesce(user_name,'-99') as user_name
,coalesce(user_age,0) as user_age
,coalesce(user_cellphone,'-99') as user_cellphone
,coalesce(create_time,cast('1700-01-01 00:00:00' as timestamp )) as create_time
,coalesce(update_time,cast('1700-01-01 00:00:00' as timestamp )) as update_time
from wedw_ods.test_user_info_20200407 b ;
--仅保留近7天的分区
alter table wedw_dwd.test_user_info_di drop if EXISTS partition(date_id='2020-03-31');
特殊增量表:da表,每天的分区就是当天的数据,其数据特点就是数据产生后就不会发生变化,如日志表
缺点:
既然全量表无法反映历史,那么要能查到历史数据情况又该怎么办呢?这个时候快照表就派上用途了
按日分区,记录截止数据日期的全量数据(每个分区里面的数据都是分区时间对应的前一天的所有全量数据,t+1)
快照表的25号分区和24号分区(都是t+1,实际时间分别对应26号和25号)的数据相减就是实际时间25号到26号有变化的、增加的数据,也就相当于增量表里面25号分区的数据。
缺点:
拉链表目的是解决快照表数据冗余问题,还能维护数据历史状态和最新状态。拉链表根据拉链粒度的不同,实际上相当于快照,只不过做了优化,去除了一部分不变的记录而已,通过拉链表可以很方便的还原出拉链时点的客户记录。
拉链表记录截止数据日期的全量数据
记录一个事物从开始,一直到当前状态的所有变化的信息;
拉链表每次上报的都是历史记录的最终状态,是记录在当前时刻的历史总量;
当前记录存的是当前时间之前的所有历史记录的最后变化量(总量);
一般只有一个分区
也可以有分区表,有些不变的数据或者是已经达到状态终点的数据就会放在分区里面,分区字段一般为开始时间:start_date
和结束时间:end_date
。一般在该天有效的数据,它的end_date是大于等于该天的日期的。
获取某一天全量的数据,可以通过表中的start_date和end_date来做筛选,选出固定某一天的数据。例如我想取截止到20190813的全量数据,其where过滤条件就是where start_date<=‘20190813’ and end_date>=20190813。
具体实现请查看:https://blog.csdn.net/silentwolfyh/article/details/89361785
适用情况:
优点
start_time
表示该条记录的生命周期开始时间——周期快照时的状态
end_time
该条记录的生命周期结束时间
end_time= ‘9999-12-31’ 表示该条记录目前处于有效状态
查询4月8日的所有有效的记录:
select * from wedw_dwd.test_user_info_dz where date_id = ‘2020-04-08’ and end_time = ‘9999-12-31’;
select * from wedw_dwd.test_user_info_dz where date_id = ‘2020-04-08’ and start_time <= ‘2020-04-07’ and end_time >= ‘2020-04-07’;
注:第一次加工的时候需要初始化所有数据,start_time设置为数据日期2020-04-06 ,end_time设置为9999-12-31
--分桶
set hive.enforce.bucketing=FALSE;
--分区
set hive.exec.dynamic.partition=FALSE;
set hive.exec.dynamic.partition.mode=nostrick;
set hive.exec.compress.output=true;
set mapred.output.compress=true;
set mapred.output.compression.type=BLOCK;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
alter table wedw_dwd.test_user_info_dz drop if EXISTS PARTITION(date_id='${HIVE_DATA_DATE}');
-- wedw_dwd.test_user_info_dz 存在, wedw_ods.test_user_info_${DATA_DATE} 不存在的
--或者都存在的闭链的 插入到 wedw_dwd.test_user_info_dz 下一个分区
insert overwrite table wedw_dwd.test_user_info_dz PARTITION(date_id='${HIVE_DATA_DATE}')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
,a.start_time
,a.end_time
from wedw_dwd.test_user_info_dz a
left join wedw_ods.test_user_info_${DATA_DATE} b on b.user_id=a.user_id and b.create_time < '${HIVE_DATA_DATE+1}'
where a.date_id = '${HIVE_DATA_DATE-1}'
and (b.user_id is null
or (b.user_id is not null and a.end_time <='${HIVE_DATA_DATE-1}')
)
;
-- 把wedw_dwd.test_user_info_dz, wedw_ods.test_user_info_${DATA_DATE} 都存在的开链的 全部闭链 插入到 wedw_dwd.test_user_info_dz 下一个分区
insert into table wedw_dwd.test_user_info_dz PARTITION(date_id='${HIVE_DATA_DATE}')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
,a.start_time
,'${HIVE_DATA_DATE-1}' end_time
from wedw_dwd.test_user_info_dz a
inner join wedw_ods.test_user_info_${DATA_DATE} b on b.user_id=a.user_id and b.create_time < '${HIVE_DATA_DATE+1}'
where a.date_id = '${HIVE_DATA_DATE-1}'
and a.end_time >'${HIVE_DATA_DATE-1}'
;
-- 把wedw_ods.test_user_info_${DATA_DATE}, 插入到 wedw_dwd.test_user_info_dz 下一个分区
insert into table wedw_dwd.test_user_info_dz PARTITION(date_id='${HIVE_DATA_DATE}')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
,'${HIVE_DATA_DATE}' start_time,
,'9999-12-31' end_time
from wedw_ods.test_user_info_${DATA_DATE} b
where b.create_time < '${HIVE_DATA_DATE+1}';
--仅保留近7天的数据
alter table wedw_dwd.test_user_info_dz drop if EXISTS partition(date_id='${HIVE_DATA_DATE-7}');
对于表的每一个修改都会记录,可以用于反映实际记录的变更。
切片表根据基础表,往往只反映某一个维度的相应数据。其表结构与基础表结构相同,但数据往往只有某一维度,或者某一个事实条件的数据