三类对象的设计纪律
Data Vault 的设计纪律可以概括成一句话:Hub 只存业务键的去重与加载信息,Link 只存关系,所有描述属性与历史一律放进 Satellite。守住这条边界,模型才能在新增源系统时只做加法;一旦把属性塞进 Hub,扩展性立刻消失。
基本信息
| Hub 主键 | 由业务键计算出的 hash 代理键 |
|---|---|
| Link 主键 | 参与关联的各 Hub 键组合的 hash |
| Satellite 拆分 | 按源系统拆,或按变更速率拆 |
| 变更检测 | 用 hashdiff 比较属性集合是否变化 |
| 加载顺序 | 先 Hub 再 Link 再 Satellite,保证外键可寻 |
典型使用场景
- 同一客户来自 CRM 与 ERP:拆成 sat_customer_crm、sat_customer_erp 两个 Satellite 分别维护
- 变更速率差异大:等级与联系方式更新频率不同,拆表避免高频更新带动全属性重写
- 源系统隔离:某个源需要重新接入或回滚,只影响对应 Satellite
- 审计追溯:每条属性变更都带加载时间与来源,能回答何时由谁写入
- 增量加载:按对象分片并行跑,同一批内互不阻塞
Satellite 加载与取数
Satellite 加载与取数
-- 变更检测:只有 hashdiff 变化才插入新的 Satellite 行
INSERT INTO sat_customer_crm(hub_customer_key, load_dts, name, level, hashdiff)
SELECT :hk, :load_dts, :name, :level, :new_hash
WHERE :new_hash <> (SELECT hashdiff FROM sat_customer_crm
WHERE hub_customer_key = :hk
ORDER BY load_dts DESC LIMIT 1); -- 与最新版本比
-- 取当前属性:按加载时间倒序取第一条
SELECT name, level FROM sat_customer_crm
WHERE hub_customer_key = :hk
ORDER BY load_dts DESC LIMIT 1; -- 历史版本完整保留在表中对象职责与常见误用
| 对象 | 正确职责 | 常见误用 |
|---|---|---|
| Hub | 业务键去重与加载信息 | 把名称、状态等属性写进 Hub |
| Link | 仅存放关系键 | 把关系的属性或度量写进 Link |
| Satellite | 属性与历史版本 | 多源属性混在一张表里,来源难追溯 |
| hash key | 统一算法生成的关联键 | 各对象算法不一致,关联大面积丢失 |
把一个实体的属性拆成多个 Satellite 是常规做法,不算设计过度:不同源的更新节奏互不干扰,某个源出问题也不会连带其他源重刷。拆分依据要写进模型文档,避免后人看到多张相似表不知所措。
Satellite 的属性变更若不做 hashdiff 比对而直接追加,同一次批量的重复投递会插入多行完全相同的版本,取最新值虽不受影响,但历史版本数量会虚假膨胀,审计结论被污染。