代理键解决什么问题
代理键是维度表里由系统生成、不含业务含义的主键(自增、序列或哈希)。事实表存代理键而不是业务键,好处有两个:业务键变更时不会断链,以及同一业务键可以存在多个历史版本(SCD 类型的必要条件)。
基本信息
| 生成方式 | 自增列、数据库序列,或对业务键计算哈希 |
|---|---|
| 维表侧 | 代理键作为主键,业务键作为普通列保留 |
| 事实侧 | 存代理键做关联,便于处理多版本维度 |
| 优点 | 隔离业务键变化,支持历史版本,加载可并行 |
| 注意 | 代理键与业务键的映射必须可回溯 |
典型使用场景
- SCD 类型 2 维度:同一业务键多个版本,必须用代理键区分
- 业务键会变:源系统重新编码或合并实体时,事实侧关联不受影响
- 多源合并:同一实体在多个系统标识不同,统一后分配同一个代理键
- 并行加载:用哈希生成减少序列单点依赖,提升加载吞吐
- 维度属性变更审计:通过代理键定位具体命中哪个版本
维表与事实表
维表与事实表
-- 维度表:代理键做主键,业务键仅作普通列保留
-- dim_product(product_sk BIGINT, product_id STRING, name STRING, ...)
-- 事实表:存代理键,不存业务键
-- fact_order(order_id STRING, product_sk BIGINT, pay_amt DECIMAL(18,2))
-- 查询时通过代理键关联到具体维度版本
SELECT p.name, sum(f.pay_amt)
FROM fact_order f
JOIN dim_product p ON f.product_sk = p.product_sk -- 用代理键关联
GROUP BY p.name;
-- 出现问题时用业务键回查代理键映射,定位到具体版本
-- SELECT product_sk, product_id FROM dim_product WHERE product_id = 'P1001';代理键生成方式对比
| 方式 | 优点 | 代价 |
|---|---|---|
| 数据库自增 | 实现简单,局部唯一 | 并行写入易冲突,跨库不可直接合并 |
| 序列 | 集中分配,顺序可控 | 依赖单点,高并发下有等待 |
| 业务键哈希 | 无单点、可并行、跨库稳定 | 存在碰撞可能,需确认算法与冲突处理 |
代理键必须与业务键保持可回溯的映射关系并保留在维度表中。否则排查数据问题时只能看到一串无意义数字,无法判断事实行到底指向哪个实体。
用业务键哈希作为代理键时,算法与输入规范化规则要在全仓统一。大小写、前后空格、拼接来源标识处理不一致,会让同一实体产生两个不同代理键,维度表出现重复成员。