什么是拉链表?详解数据仓库中的历史表设计与实现
创作时间:
作者:
@小白创作中心
什么是拉链表?详解数据仓库中的历史表设计与实现
引用
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,但加上后能优化很多查询。 - 可以添加当前行状态标识,快速定位当前状态。
- 可以在状态中添加额外字段,如当天修改次数,增强拉链表的功能。
热门推荐
房屋过户全攻略:从产权核实到手续办理,确保交易合法合规
闵行区2024年预计盘活1000亩产业用地,创新实践助力高质量发展
壹粉教你自制蜂蜜柚子茶,温暖过冬!
奥尔良蜂蜜烤鸡翅,宅家必学!
秋冬养生必备:蜂蜜姜茶的功效与制作方法
蜂蜜燕麦早餐新吃法:营养美味又省时
薑黃蜂蜜檸檬:都市人的健康饮品新选择
地黄、麦冬、天冬、化橘红被列入食药,它们有啥用?一文了解
没事儿吃点益生菌,有病治病,没病强身
德奎万氏腱鞘炎
全球首部CMVD中西结合诊治指南发布:复方丹参滴丸获推荐
世界蜜蜂日:蜜蜂采蜜对植物生态的影响与保护
蜂蜜抗菌效果惊人!但能替代抗生素吗?
秋冬养生必备:蜂蜜+柠檬/姜/枸杞的养生之道
白细胞偏低要吃什么?这些食物有助于提升白细胞数量
削减15亿美元成本,裁员2200人|BMS最新公告
抖音热推:东莞烧鹅带火地方经济
《寻味东莞》+《烟火石龙》,揭秘东莞美食文化
体检仅需5分钟!特克斯驾驶人自助体检机上岗
阿根廷用牛肉换华为基站,俄罗斯用木材抵奇瑞货款?
《少年歌行》天女蕊技能详解:前中期最强“万精油”侠客
《落凡尘》:新中式美学的国漫新篇
上海科技馆携手上海交通大学举办全国科普日专场活动,送上满满科普干货
新能源汽车下乡,如何打通“最后一公里”?
蜂蜜水:从饮品到良药的医用价值
适合接种流感疫苗的人群及接种指南
从《乘风破浪的姐姐》到国漫女神:女性力量的崛起
如何高性价比选择DIY装机配件:从小白到进阶的系统指南
装机兼容性很重要看了这些就不用担心?如何确保电脑硬件完美配合?
好看的民国剧大全,《战长沙》、《觉醒年代》、《半生缘》上榜