单张表超过30个字段_拉链表

本文介绍了拉链表的概念及其在数据仓库中的应用,主要用于节省存储空间和处理缓慢变化的数据。通过实例展示了如何在用户信息表中利用拉链表来记录数据的历史快照,以及如何通过SQL操作进行数据的更新和维护。拉链表的设计包括初始化、临时表的创建、数据插入等步骤,有效地解决了大规模数据更新的问题。
摘要由CSDN通过智能技术生成

a0ebaa061b772f13dd7e8e3624bb863c.png

为什么要做拉链表

拉链表适合于:数据会发生新增和变化,但是大部分是不变的,且是缓慢变化的(如电商中用户信息表中的手机号不可能每天都变化),如果是快速变化的(如每天一变),则每天做全量更新(事务型事实表)。主要目的是节省存储空间。

拉链表的使用场景

在数据仓库的数据模型设计过程中,经常会遇到下面这种表的设计:

  • 1 有一些表的数据量很大,比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。
  • 2 表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。
  • 3 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。
  • 4 表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小

什么是拉链表

记录每条信息的生命周期,一旦一条信息的生命周期结束,就重新开始一条新纪录,并把当前日期放入生效日期。 如果当前日期至今有效,在结束日期放入一个最大值,例如(9999-99-99)

0ad42054cbc2317c81801e8be42ab1f1.png

- 优势:订单1经历了四个生命周期,如果每天增量同步数据,则一年有365条数据,而拉链表只会产生4条数据

制作拉链表

首先初始化拉链表

通常要在原表的基础上加入start_date,end_date,并从原表导入数据到拉链表

drop table if exists dwd_order_info_his;
create external table dwd_order_info_his(
    `id` string COMMENT '订单编号',
    `order_status` string COMMENT '订单状态',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链表'

4de4eae211c024b4296908dfd63f6fdf.png

创建临时表整个中间数据

临时表和拉链表表结构一致,只是为了存储中间过程。

drop table if exists dwd_order_info_his_tmp;
create external table dwd_order_info_his_tmp(
    `id` string COMMENT '订单编号',
    `order_status` string COMMENT '订单状态',
    `start_date`  string COMMENT '有效开始日期',
    `end_date`  string COMMENT '有效结束日期'
) COMMENT '订单拉链临时表'

向临时表中插入数据

插入前,拉链表数据

94ea88b45098ca8109f998a05e1ce844.png

订单新增表数据

3468d5f35e2f78254f9498bf2ae57654.png

插入数据后

f1a8ad1dc070ac119874f94d02710718.png

订单1和订单2,订单状态都发生了改变,产生了新数据

具体sql

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   
)his 
order by his.id, start_date;

分为两个部分数据 第一部分把新增修改表直接插入,这部分数据都是新鲜的,end_date是9999-99-99

第二部分是原拉链表和新增变化表做左连接,原表存在id且终止时间为无限的数据会保留,说明这部分数据需要变更。(如果右表id为空,说明这部分数据没有任何改变,end_date保持不变,如果右表数据存在,说明经过了改变,则,end_date需要减1),所以这部分完成了历史数据的更改

将拉链表数据用临时表覆盖

因为hive修改字段值不方便,直接全变覆盖

insert overwrite table dwd_order_info_his 
select * from dwd_order_info_his_tmp;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值