拉链表(SCD Type 2 / Slowly Changing Dimension Type 2)
拉链表在维度属性变化时关闭旧版本、插入新版本,并用有效时间区间保存每个版本何时生效,从而可以按历史时间点还原属性。
客户等级和所属机构会变化,但分析历史贷款时,应该还能还原当时的客户状态。
拉链表在维度属性变化时关闭旧版本、插入新版本,并用有效时间区间保存每个版本何时生效,从而可以按历史时间点还原属性。
Customer C001 在 2025 年是普通客户,所属机构是杭州支行。2026 年 4 月 1 日,客户等级变为 VIP,所属机构变为上海支行。现在分析 2025-10-10 的 LoanNote N001,业务需要知道客户当时是什么状态。
如果维度表只保留今天的值,查询历史贷款时只能读到 VIP 和上海支行。问题不是客户资料不能更新,而是当前属性和历史分析所需的属性有不同的时间语义。
先写入客户等级和机构变更,再在覆盖更新与拉链表之间切换;把业务日期游标停在 2026-03-31 与 2026-04-01,查看 [start_date, end_date) 区间如何决定 N001 命中的 Customer 版本。
两种策略都可能合理,关键是历史分析是否需要保留属性变化前的版本。
customer_id 说明“是哪位客户”,是跨时间稳定的业务键;customer_sk 说明“这个客户的哪一个属性版本”。历史查询先用 customer_id 找到版本集合,再用 LoanNote 的 disbursedDate 判断落在哪个有效区间。
本例的两个版本按 [start_date, end_date) 写成:101 / C001 / 普通 / 杭州支行 / [2025-01-01, 2026-04-01),以及 205 / C001 / VIP / 上海支行 / [2026-04-01, 9999-12-31)。旧版本存下的 end_date 是 2026-04-01,但它不包含这一天,业务上等价于覆盖到 2026-03-31;变更日属于新版本。
2026-04-01,客户从普通变为VIP。
2025-10-10 · C001 · ¥300,000
先执行客户变更,再切换两种策略看历史 LoanNote 的结果。
直接更新 level 和 branch 后,杭州支行与普通等级不再出现在当前行中。
customer_id | level | branch |
|---|---|---|
| C001 | 普通 | 杭州支行 |
customer_id 说明“是哪位客户”,customer_sk 说明“这位客户的哪一个历史版本”。
把业务日期游标停在任意一天,观察 [start_date, end_date) 如何决定命中的 customer_sk 与历史属性。
start 包含(≤),end 不包含(<);变更日 2026-04-01 只属于新版本。 Type 1 没有版本边界:只有一行覆盖更新,整段时间都返回同一行当前属性。
customer_sk 101当前命中2025-01-01 ≤ t < 9999-12-31普通 · 杭州支行 · 开放结束
Type 1 没有版本边界:这 4 天都返回同一行当前属性。
N001 的实际放款日就是 2025-10-10,这是真实的历史查询。