本文为迁移自掘金的文章,原始链接:大数据-247 离线数仓 - 电商分析 Hive 拉链表实战
TL;DR
- 场景:离线数仓中需要低成本保存订单历史状态,同时支持按天回溯与变化分析
- 方案:用 ODS 日增量表 + DWD 拉链表,比”只留最新”与”每天存全量”更平衡
- 产出:Hive 拉链表初始化、增量刷新 SQL、闭链规则与常见错误速查
什么是拉链表
拉链表(Slowly Changing Dimension Type 2)是数据仓库中常用的一种维度表设计方式,用于记录数据的历史变化。
场景举例
假设有订单表:
- 6月20日:3条记录(001/002/003)
- 6月21日:5条记录,新增2条(004/005),修改1条(001)
- 6月22日:6条记录,新增1条(006),修改2条(003/005)
常见处理方式:
| 方案 | 问题 |
|---|---|
| 只保留最新 | 无法查看历史状态 |
| 每天存全量 | 存储浪费,数据重复 |
拉链表可以很好地平衡这个问题:
-- 拉链表结构
CREATE TABLE dwd_orders(
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING,
start_date STRING, -- 有效期开始
end_date STRING -- 有效期结束,'9999-12-31' 表示当前有效
);
拉链表实现
前提条件
- ODS 层有订单表,数据按日分区,存放每天的增量数据
- 订单状态包括:创建、支付、完成
- 刷新频率为一天,当天获取前一天的增量数据
全量初始化
-- 加载初始数据
LOAD DATA LOCAL INPATH '/data/order1.dat' INTO TABLE test.ods_orders PARTITION(dt='2020-06-20');
-- 初始化拉链表
INSERT OVERWRITE TABLE test.dwd_orders
SELECT
orderid,
createtime,
modifiedtime,
status,
createtime AS start_date,
'9999-12-31' AS end_date
FROM test.ods_orders
WHERE dt='2020-06-20';
增量刷新
-- 1. 处理新增数据
INSERT OVERWRITE TABLE test.dwd_orders
SELECT
orderid,
createtime,
modifiedtime,
status,
modifiedtime AS start_date,
'9999-12-31' AS end_date
FROM test.ods_orders
WHERE dt = '2020-06-21'
UNION ALL
-- 2. 处理历史数据(闭链)
SELECT
A.orderid,
A.createtime,
A.modifiedtime,
A.status,
A.start_date,
CASE
WHEN B.orderid IS NOT NULL AND A.end_date > '2020-06-21'
THEN '2020-06-20' -- 闭链日期
ELSE A.end_date
END AS end_date
FROM test.dwd_orders A
LEFT JOIN (
SELECT * FROM test.ods_orders WHERE dt = '2020-06-21'
) B ON A.orderid = B.orderid;
查询某天快照
-- 查询 2020-06-21 当天的订单状态
SELECT *
FROM dwd_orders
WHERE start_date <= '2020-06-21'
AND end_date >= '2020-06-21';
常见错误速查
| 症状 | 根因 | 修复 |
|---|---|---|
| 同一订单多条”9999-12-31”未闭合 | 增量刷新时只插入新数据,旧链未正确闭链 | 检查 end_date='9999-12-31' 的记录数 |
| 历史区间重叠 | 闭链日期计算错误 | 按 orderid 排序检查日期区间 |
| 查询某天快照结果不对 | 筛选条件错误 | 检查是否按日期区间过滤 |
| 新增订单正常,修改订单丢失历史 | 直接覆盖,未保留旧版本 | 比较刷新前后记录条数 |
| 每日跑批后数据翻倍 | UNION ALL 边界不清 | 检查增量日是否重复执行 |
小结
拉链表是离线数仓中处理历史状态变化的有效方案:
- 优点:兼顾历史追溯与存储成本
- 关键:正确处理增量闭链逻辑
- 注意:做好幂等控制,避免重复执行导致数据翻倍
本文首发于 掘金