什么是拉链表?详解数据仓库中的历史表设计与实现
创作时间:
作者:
@小白创作中心
什么是拉链表?详解数据仓库中的历史表设计与实现
引用
CSDN
1.
https://blog.csdn.net/KevinDeng35/article/details/128015357
拉链表(也称为历史表)是数据仓库中处理历史数据变更的一种重要技术手段。它能够记录一个事物从开始到当前状态的所有变化信息,广泛应用于需要查看历史快照信息的场景。本文将详细介绍拉链表的概念、使用场景、设计原理以及在Hive中的具体实现方法。
拉链表的使用场景
在数据仓库的数据模型设计过程中,经常会遇到以下几种表的设计需求:
- 有一张用户表,数据量很大(例如50多个字段,约10亿条记录),即使使用ORC压缩,单张表的存储也会超过100G,HDFS中三副本存储会更大。
- 表中的部分字段会被更新,如用户联系方式、产品描述信息、订单状态等。
- 需要查看某一个时间点或时间段的历史快照信息,比如查看某一订单在历史某一时间点的状态。
- 表中的记录变化的比例和频率不是很大,例如总共有10亿用户,每天新增和发生变化的约200万左右,变化比例很小。
针对上述需求,常见的解决方案有三种:
- 方案一:每天只保留最新的一份数据,优点是节省空间且使用方便,但缺点是没有历史数据,查看历史数据需要通过其他方式。
- 方案二:每天保留一份全量的切片数据,优点是保留了历史数据,但缺点是存储空间消耗巨大。
- 方案三:使用拉链表。
为什么使用拉链表
拉链表在使用上兼顾了存储空间和数据查询的需求:
- 存储空间:虽然不像方案一那样占用空间少,但每日的增量可能只有方案二的千分之一甚至是万分之一。
- 数据查询:既能获取最新的数据,也能通过添加筛选条件获取历史数据。
拉链表的设计和实现
以电商网站的用户表为例,说明拉链表的设计原理:
- t_start_date:表示该条记录的生命周期开始时间。
- t_end_date:表示该条记录的生命周期结束时间,如果为'9999-12-31'则表示该条记录目前处于有效状态。
查询示例:
- 查询当前所有有效记录:
SELECT * FROM user WHERE t_end_date = '9999-12-31' - 查询2017-01-02的历史快照:
SELECT * FROM user WHERE t_start_date <= '2017-01-02' AND t_end_date >= '2017-01-02'
在Hive中实现拉链表
在大数据场景下,基于HDFS和Hive的数据仓库架构中实现拉链表:
- 数据源准备:
- ODS层的用户全量表(用于初始化)
- 每日用户更新表(可通过监听MySQL变化、对比切片数据、使用流水表等方式获取)
- 表结构设计:
- ODS层用户表
CREATE EXTERNAL TABLE ods.user ( user_num STRING COMMENT '用户编号', mobile STRING COMMENT '手机号码', reg_date STRING COMMENT '注册日期' ) PARTITIONED BY (dt string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS ORC LOCATION '/ods/user'; - ODS层用户更新表
CREATE EXTERNAL TABLE ods.user_update ( user_num STRING COMMENT '用户编号', mobile STRING COMMENT '手机号码', reg_date STRING COMMENT '注册日期' ) PARTITIONED BY (dt string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS ORC LOCATION '/ods/user_update'; - 拉链表
CREATE EXTERNAL TABLE dws.user_his ( user_num STRING COMMENT '用户编号', mobile STRING COMMENT '手机号码', reg_date STRING COMMENT '用户编号', t_start_date, t_end_date ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS ORC LOCATION '/dws/user_his';
- 实现SQL语句:
假设已经初始化了2017-01-01的日期,需要更新2017-01-02的数据:INSERT OVERWRITE TABLE dws.user_his SELECT * FROM ( SELECT A.user_num, A.mobile, A.reg_date, A.t_start_time, CASE WHEN A.t_end_time = '9999-12-31' AND B.user_num IS NOT NULL THEN '2017-01-01' ELSE A.t_end_time END AS t_end_time FROM dws.user_his AS A LEFT JOIN ods.user_update AS B ON A.user_num = B.user_num UNION SELECT C.user_num, C.mobile, C.reg_date, '2017-01-02' AS t_start_time, '9999-12-31' AS t_end_time FROM ods.user_update AS C ) AS T;
补充说明
- 拉链表与流水表:流水表存放的是用户的每次变更记录,而拉链表只保留每天的状态。
- 查询性能优化:
- 在查询引擎中对
start_date和end_date设计索引。 - 保留部分历史数据,例如一张表存放全量拉链数据,另一张表只提供近3个月数据。
总结
拉链表在数据仓库中处理历史数据变更时具有重要价值:
- 可以不加
t_end_date,但加上后能优化很多查询。 - 可以添加当前行状态标识,快速定位当前状态。
- 可以在状态中添加额外字段,如当天修改次数,增强拉链表的功能。
热门推荐
央视频 vs 咪咕视频:谁才是你的追剧神器?
摸看按:ATM机取款防骗三步法,守护资金安全
用钢尺玩转音乐实验,揭秘音调秘密
山茶花养护秘籍,让你的花园惊艳四座
利可君片治疗血液病获突破,有效提升白细胞和血小板水平
冠心病患者使用智能心率监测设备指南:从选购到注意事项
口腔激光治疗新突破:七大应用,告别传统牙科恐惧
靶向递送VEGFA mRNA,LuLNP疗法显著改善肺部修复
气象预报揭秘:雨是怎么形成的?
1980版2元纸币:普通版30元,绿钻版价超70元
水循环的秘密:揭秘雨水形成全过程
个人职业发展如何在企业文化中实现自我价值的最大化
参松养心胶囊:纯中药制剂双向调节心律失常
西洋参:养阴清热功效佳,这些人不宜食用
松下幸之助:以人为本,让产品像自来水一样普及
冬季咽喉炎高发,科学喝水护嗓指南
别再盲目喝粥了,这才是科学养胃之道
电子秤干扰防范技术新突破:让称重更精准安全
白蜡木打造顶级美式家具:自然之美与精湛工艺的完美融合
舟山虾:海中珍品的养生密码
UEGW研究:单胶囊四联疗法根除幽门螺旋杆菌达93%,10天疗程安全有效
研究证实:吸烟是甲状腺疾病的重要诱因,患者应及早戒烟
大唐狄公案开播:8年匠心打造“东方福尔摩斯”传奇
基于物联网的温室农业种植环境监控系统研究
广西河池早熟人参果种植技术详解
钛合金成形工艺助力航空航天
康熙帝的神操作:泸定桥的秘密
泸定桥打卡,探秘泸定县古城
线性混合效应模型:统计学课程必备神器
十二生肖背后的秘密:谁才是真正的赢家?