大数据-247 离线数仓 - Hive 拉链表实战:订单历史状态增量刷新
TL;DR
- 场景: 离线数仓中需要低成本保存订单历史状态,同时支持按天回溯与变化分析
- 结论: 用 ODS 日增量表 + DWD 拉链表,比”只留最新”与”每天存全量”更平衡
- 产出: 给出 Hive 拉链表初始化、增量刷新 SQL、闭链规则与常见错误速查
周期性事实表定义
周期性事实表记录的是定期发生的业务事件或度量数据,例如每天、每月或每季度的数据。其设计目的在于帮助用户快速查询和分析这些周期性数据的趋势和变化。
拉链表实现
ODS 层订单表
DROP TABLE test.ods_orders;
CREATE TABLE test.ods_orders(
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING
) PARTITIONED BY (dt STRING)
row format delimited fields terminated by ',';
DWD 层订单拉链表
DROP TABLE test.dwd_orders;
CREATE TABLE test.dwd_orders(
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING,
start_date STRING,
end_date STRING
)
row format delimited fields terminated by ',';
全量初始化
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';
增量刷新
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
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 dwd_orders A
LEFT JOIN
(SELECT * FROM ods_orders WHERE dt = '2020-06-21') B
ON A.orderid = B.orderid;
错误速查
| 症状 | 根因定位 | 修复 |
|---|---|---|
| 拉链表出现同一订单多条”9999-12-31”未闭合记录 | 增量刷新时只插入新数据,旧链未正确闭链 | 查 orderid 分组后 end_date=‘9999-12-31’ 数量是否大于 1 |
| 历史区间重叠 | start_date、end_date 计算不一致,闭链日期写错 | 按 orderid 排序检查日期区间是否交叉 |
| 查询某天快照结果不对 | 快照筛选条件写错 | 检查是否用 dt 查 DWD,或没按日期区间过滤 |
| 新增订单正常,修改订单丢失历史 | 直接覆盖了原记录,没有保留旧版本 | 比较刷新前后同一 orderid 记录条数 |
| 每日跑批后数据翻倍 | UNION ALL 前后集合边界不清,历史表全量重复拼接 | 检查增量日是否重复执行,检查是否缺少幂等控制 |