star schema表中查找primary key:单字段重复时如何确定事实表外键
方案建议
你当前的用户维度表样例数据如下:
| Name | |
|---|---|
| amy | amy@gmail.com |
| jess | amy@gmail.com |
这种单字段无法保证唯一、组合字段可唯一识别记录的场景,不推荐直接用两列组成的复合键作为事实表的外键,星型模型设计的最佳实践是使用无业务含义的代理键,具体原因和方案如下:
复合键作为外键的核心弊端
- 存储成本高:事实表的数据量通常是维度表的成百上千倍,额外存储一个字符串字段的累计开销非常高
- 查询性能差:多字段关联的执行效率远低于单字段关联,且字符串对比的性能也远低于整数类型
- 扩展性极差:如果后续业务规则调整,比如允许用户修改邮箱、或者出现同姓名同邮箱的多账号场景,复合键逻辑会直接失效,还需要同步修改所有关联事实表的字段,维护成本极高
最优实现方案
给该维度表新增一列整数类型的代理键作为主键,例如命名为user_sk(surrogate key),每一组唯一的(Name, Email)对应唯一的user_sk值,调整后的维度表结构如下:
| user_sk | Name | |
|---|---|---|
| 1 | amy | amy@gmail.com |
| 2 | jess | amy@gmail.com |
后续事实表只需要存储user_sk作为外键关联维度表即可,完全满足唯一性要求,同时兼顾性能和后续扩展性。
如果确实有必须使用业务键的特殊场景,才考虑使用复合外键,建议提前做足业务规则变更的风险评估。
内容的提问来源于stack exchange,提问作者Humza Iftikhar
相关产品推荐
相关产品推荐

