Hive数据仓库之全量表、增量表、快照表、切片表和拉链表

数据仓库中常见的一些表:
全量表:记录每天的所有的最新状态的数据,
增量表:记录每天的新增数据,增量数据是上次导出之后的新数据。
快照表:按日分区,记录截止数据日期的全量数据
切片表:切片表根据基础表,往往只反映某一个维度的相应数据。其表结构与基础表结构相同,但数据往往只有某一维度,或者某一个事实条件的数据

拉链表:记录每条信息的生命周期,当一条记录的生命周期结束,就会重新开始一条新的记录,并把当前日期放入生效开始日期。如果当前信息至今有效,则在生效结束日期中填入一个极大值(如9999-99-99),一般在数仓中通过增加start_date ,end_date 两列来表示。

这里重点介绍一下拉链表:
1、为什么要做拉链表?
拉链表适合于:数据会发生变化,但是大部分是不变的。比如常见的订单表,里面的订单信息的订单状态字段会从未支付、已支付、未发货、已完成等状态经历一周甚至更长的时间,但实际上大部分时间是不变的。
在实际生产环境中,如果数据量规模较大,那么按照每日全量的方式保存效率就会很低了。比如下图中的对比:
在这里插入图片描述
2、如何使用拉链表?
通过,生效开始日期<=某个日期 且 生效结束日期>=某个日期,能够得到某个时间点的数据全量切片。
比如:
查询2019-01-01的历史快照,则select * from dwd_order_info_his where start_date <= ‘2019-01-01′ and end_date >= ‘2019-01-01’
查询当前所有有效的记录,则select * from dwd_order_info_his where end_date = ‘9999-99-99′

3、拉链表的形成过程,比如下图:
在这里插入图片描述
4、如何制作拉链表?
1)新建和初始化拉链表dwd_order_info_his(首次独立执行)

drop table if exists dwd_order_info_his;
create external table dwd_order_info_his(
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额',
    `order_status` string COMMENT '订单状态',
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',
    `out_trade_no` string COMMENT '支付流水号',
    `create_time` string COMMENT '创建时间',
    `operate_time` string COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链表'
stored as parquet
location '/warehouse/gmall/dwd/dwd_order_info_his/'
tblproperties ("parquet.compression"="snappy");

insert overwrite table dwd_order_info_his
select
    id,
    total_amount,
    order_status,
    user_id,
    payment_way,
    out_trade_no,
    create_time,
    operate_time,
    '2019-02-13',
    '9999-99-99'
from ods_order_info oi
where oi.dt='2019-02-13';

2)获取当日变动数据:包括新增和修改(每日执行)

//当天的订单变化表dwd_order_info数据获取:
INSERT overwrite TABLE dwd_order_info PARTITION (day = '2019-02-14')
SELECT orderid,status
FROM orders
WHERE (createtime = '2019-02-14'  and modifiedtime = '2019-02-14') OR modifiedtime = '2019-02-14';

3)合并变动数据和旧拉链表数据(有更新的信息需要修改生效结束日期,无更新的信息生效结束日期不变)之后插入到临时表中
比如下图:
在这里插入图片描述

//建立临时拉链表:
drop table if exists dwd_order_info_his_tmp;
create table dwd_order_info_his_tmp( 
    `id` string COMMENT '订单编号',
    `total_amount` decimal(10,2) COMMENT '订单金额', 
    `order_status` string COMMENT '订单状态', 
    `user_id` string COMMENT '用户id' ,
    `payment_way` string COMMENT '支付方式',  
    `out_trade_no` string COMMENT '支付流水号',  
    `create_time` string COMMENT '创建时间',  
    `operate_time` string COMMENT '操作时间',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链临时表'
stored as parquet
location '/warehouse/gmall/dwd/dwd_order_info_his_tmp/'
tblproperties ("parquet.compression"="snappy");

//数据插入到临时拉链表:
insert overwrite table dwd_order_info_his_tmp
select * from 
(
select 
id,
    total_amount,
    order_status,
    user_id,
    payment_way,
    out_trade_no,
    create_time,
    operate_time,
    '2019-02-14' start_date,
    '9999-99-99' end_date
from dwd_order_info where dt='2019-02-14'

union all 
select oh.id,
    oh.total_amount,
    oh.order_status,
    oh.user_id,
    oh.payment_way,
    oh.out_trade_no,
    oh.create_time,
    oh.operate_time,
    oh.start_date,
    if(oi.id is null, oh.end_date, date_add(oi.dt,-1)) end_date
from dwd_order_info_his oh left join 
     (
select
*
from dwd_order_info
where dt='2019-02-14'
) oi
     on oh.id=oi.id and oh.end_date='9999-99-99'  
)his 
order by his.id, start_date;

4)用临时表覆盖旧拉链表

insert overwrite table dwd_order_info_his 
select * from dwd_order_info_his_tmp;

至此,就可以去查询新的拉链表数据:select * from dwd_order_info_his;


版权声明:本文为weixin_43230682原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。