5.1 KiB
5.1 KiB
SCD2 缓慢变化维处理规则
本文档定义 billiards_dwd 模式下维度表的 SCD2(Slowly Changing Dimension Type 2)处理策略、
生效区间管理和版本控制规则。
状态:骨架文档,各维度表的跟踪字段与变更触发条件待补充。
1. 概述
1.1 什么是 SCD2
SCD2 通过保留维度记录的历史版本来追踪属性变化。当被跟踪字段发生变更时:
- 关闭当前版本(设置结束时间、标记为非当前)
- 插入新版本(设置开始时间、标记为当前)
1.2 实现模块
- 处理器:
scd/scd2_handler.py—SCD2Handler类 - 核心方法:
upsert(table_name, natural_key, tracked_fields, record, effective_date) - 返回值:
INSERT(新记录)、UPDATE(属性变更)、UNCHANGED(无变化)
2. SCD2 元数据字段
所有维度表统一包含以下 SCD2 控制字段:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
scd2_start_time |
TIMESTAMPTZ |
now() |
版本生效起始时间 |
scd2_end_time |
TIMESTAMPTZ |
'9999-12-31' |
版本失效时间(9999-12-31 表示当前有效) |
scd2_is_current |
INT |
1 |
当前版本标记(1 = 当前,0 = 历史) |
scd2_version |
INT |
1 |
版本号(自增) |
约束
- 主键:
(natural_key, scd2_start_time)— 同一自然键的不同版本通过生效时间区分 - 唯一索引:
WHERE scd2_is_current = 1— 保证每个自然键只有一条当前记录 - 排他约束(GiST):
tstzrange(scd2_start_time, scd2_end_time)— 防止同一自然键的版本时间段重叠
3. 处理流程
收到维度记录
│
▼
按 natural_key 查找 valid_to IS NULL 的当前记录
│
├── 不存在 → INSERT 新记录(is_current=1, valid_from=now)
│
└── 存在 → 比较 tracked_fields
│
├── 无变化 → UNCHANGED(跳过)
│
└── 有变化 → UPDATE 旧记录(valid_to=now, is_current=0)
INSERT 新记录(valid_from=now, is_current=1)
4. 维度表 SCD2 配置
4.1 门店维度(dim_site / dim_site_ex)
- Schema:
billiards_dwd - 自然键:
site_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.2 台桌维度(dim_table / dim_table_ex)
- Schema:
billiards_dwd - 自然键:
table_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.3 助教维度(dim_assistant / dim_assistant_ex)
- Schema:
billiards_dwd - 自然键:
assistant_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.4 会员维度(dim_member / dim_member_ex)
- Schema:
billiards_dwd - 自然键:
member_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.5 会员卡账户维度(dim_member_card_account / dim_member_card_account_ex)
- Schema:
billiards_dwd - 自然键:
member_card_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.6 商品维度(dim_tenant_goods / dim_tenant_goods_ex / dim_store_goods / dim_store_goods_ex)
- Schema:
billiards_dwd - 自然键:
tenant_goods_id/site_goods_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.7 商品分类维度(dim_goods_category)
- Schema:
billiards_dwd - 自然键:
category_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
4.8 团购套餐维度(dim_groupbuy_package / dim_groupbuy_package_ex)
- Schema:
billiards_dwd - 自然键:
groupbuy_package_id - 跟踪字段:(待定义)
- 变更触发场景:(待补充)
5. 查询约定
获取当前有效记录
SELECT * FROM billiards_dwd.dim_member
WHERE scd2_is_current = 1;
获取某时间点的历史快照
SELECT * FROM billiards_dwd.dim_member
WHERE scd2_start_time <= '2025-06-01'
AND scd2_end_time > '2025-06-01';
获取某记录的完整变更历史
SELECT * FROM billiards_dwd.dim_member
WHERE member_id = 12345
ORDER BY scd2_start_time;
6. 注意事项
- 时区:
scd2_start_time/scd2_end_time使用TIMESTAMPTZ,统一以服务器时区存储 - 并发安全:当前实现在单次 ETL 运行内串行处理,未做行级锁;并发写入需额外保护
- 删除策略:维度记录不做物理删除,仅通过关闭版本(
scd2_is_current = 0)标记失效
维护约定
- 新增维度表时,须在本文档添加对应章节
- 跟踪字段变更时,须同步更新文档并评估历史数据影响
- 文档统一 UTF-8 编码,中文撰写