什么是拉链表?详解数据仓库中的历史表设计与实现
创作时间:
作者:
@小白创作中心
什么是拉链表?详解数据仓库中的历史表设计与实现
引用
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,但加上后能优化很多查询。 - 可以添加当前行状态标识,快速定位当前状态。
- 可以在状态中添加额外字段,如当天修改次数,增强拉链表的功能。
热门推荐
海南学校全力备战2025年春季学期开学
海南中小学2025年寒假开学时间确定!
海南大学开学季:科研创新与校园生活双丰收
冬季臭氧污染不容忽视:成因、危害与防护指南
臭氧:饮用水处理的秘密武器
肺腺癌晚期呕吐不止,中医如何调理?
天健美食坊教你炒毛肚,简单美味!
秋冬滋补首选:辣炒毛蚶
南北朝史:陆令萱如何影响北齐王朝的兴衰
齐后主高纬:北齐末代皇帝,他的一生有着怎样的经历?
痛风患者如何在压力山大时保持好心态?
痛风急性发作,最快几天能好?
郭麒麟同款痛风急救法:中医有妙招!
武汉开学遇小雨,家长如何安全送学?
阿萨姆红茶冻解冻技巧大揭秘!
车厘子的功效与作用有哪些
孔子登泰山:思想境界的升华与文化交融
探访芒砀山:孔子避雨遗迹的文化之旅
孔子登泰山:一次登山与文化交融的哲学之旅
育肥猪得了厌食症怎么解决呢
成都三日游必打卡:人民公园鹤鸣茶馆深度体验攻略
冬日成都三日游:历史文化探秘之旅
冬日打卡:都江堰&熊猫基地,成都周边游必选!
春节打卡:永泰古民居三对厝+李花花海
济南十大景点全攻略:从泉城明珠到文化瑰宝
从边城出发,打卡川渝最美自驾线!
臭氧疗法新突破:从疼痛治疗到医保规范
鲜藕怎么处理不变黑?
五一解锁金海雪山新玩法!
金海雪山冬季打卡指南:雪景+美食