数据仓库图解交互式教材
数据建模维度为什么要保存历史?——拉链表
学习进度0 / 64
EN
首页课程学习维度为什么要保存历史?——拉链表
2-5数据建模14 分钟

维度为什么要保存历史?——拉链表

客户等级和所属机构会变化,但分析历史贷款时,应该还能还原当时的客户状态。

维度历史拉链表代理键
核心概念

拉链表(SCD Type 2 / Slowly Changing Dimension Type 2)

拉链表在维度属性变化时关闭旧版本、插入新版本,并用有效时间区间保存每个版本何时生效,从而可以按历史时间点还原属性。

客户升级以后,2025 年的贷款算哪个等级?

Customer C001 在 2025 年是普通客户,所属机构是杭州支行。2026 年 4 月 1 日,客户等级变为 VIP,所属机构变为上海支行。现在分析 2025-10-10 的 LoanNote N001,业务需要知道客户当时是什么状态。

如果维度表只保留今天的值,查询历史贷款时只能读到 VIP 和上海支行。问题不是客户资料不能更新,而是当前属性和历史分析所需的属性有不同的时间语义。

  • customer_id = C001:稳定的客户业务 identity。
  • customer_sk = 101 / 205:某一个客户历史版本的代理键。
  • 历史 LoanNote N001:2025-10-10,放款本金 ¥300,000。
历史版本实验 · 时间点还原

同一个 customer_id,保留两个时间版本

先写入客户等级和机构变更,再在覆盖更新与拉链表之间切换;把业务日期游标停在 2026-03-31 与 2026-04-01,查看 [start_date, end_date) 区间如何决定 N001 命中的 Customer 版本。

正在加载交互实验…
放在一起看

覆盖更新还是拉链表:看查询是否需要“当时”

两种策略都可能合理,关键是历史分析是否需要保留属性变化前的版本。

覆盖更新(SCD Type 1)

只保存当前属性

  • 实现简单,维度只保留一行
  • 适合只关心今天值的属性
  • 2025 年的 N001 会读到 VIP、上海支行
拉链表(SCD Type 2)

按有效区间保存历史

  • 关闭旧行并插入新版本
  • 适合需要还原历史语义的属性
  • N001 可以命中普通、杭州支行的旧版本

两个 key,各自回答不同问题

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;变更日属于新版本。