我听说过一些参考文献,事实表上不需要 pk。我相信每桌都应该有一个pk。
如果没有 pk 和 10+ 外键,一个人如何理解事实表中的一行。
主键在那里
...但是在
数据库级别强制执行
primary key
约束是不需要的。
如果您考虑一下这一点,从技术上讲,唯一键或主键是唯一定义每行特征的键。它可以由该实体的多个属性组成。现在,对于事实表来说,从其他维度表流入的
foreign keys
一起已经充当了复合主键。这些外键组合可以“唯一”地标识事实表中的每条记录。因此,这个外键组合是事实表的主键。
那为什么不使用代理键呢?现在,如果您愿意,您可以为事实表定义一个“代理键”。但这有什么用呢?您永远不会从该事实表中检索引用其代理键的一条记录(而是使用索引)。您也不会使用该代理键将事实与其他表连接起来。这样的代理键将完全浪费数据库的空间。
强制数据库约束
当您在数据库级别定义此概念性主键时,数据库需要确保在对其执行的任何 DML 操作中都不会违反此约束。确保此约束是数据库的开销。对于 OLTP 系统来说,这可能无关紧要,但对于批量加载数据的大型 OLAP 系统来说,这可能会带来严重的“性能”损失。此外,当您可以在数据加载阶段本身(通常通过 ETL 编码)确保约束的完整性时,为什么您希望数据库确保约束的完整性。
原则上事实表应该有一个键,你是绝对正确的。从数据建模的角度来看,这是必需的。然而在实现中,数据库中的关键约束通常需要索引。创建和维护索引的开销使得“关键”属性的唯一性有时由集成层中的控件(“ETL 过程”)而不是数据库中的约束来维护。 只要可行,在数据库中创建键约束确实有意义。如果数据库中没有明确定义密钥,那么应该为用户清楚地记录下来,以便他们能够理解数据的含义。
正如您在其他答案中所读到的那样,不需要主键约束,事实表代理键在物理层面可能会有所帮助。
这是事实表代理键的 Kimball 设计技巧:
有时,组织的业务规则合法地允许事实表存在多个相同的行。通常作为 设计师,您可以通过搜索源代码来不惜一切代价避免这种情况 系统使用某种事务时间戳来制作行 独特的。但有时你会被迫接受这种不受欢迎的情况 输入。在这些情况下,有必要创建一个代理 事实表的键以允许加载相同的行。
某些用于更新事实行的 ETL 技术仅在将代理键分配给事实行时才可行。具体来说,一 加载事实行更新的技术是将行插入到 更新为新行,然后作为第二步删除原始行 作为单一交易。 ETL 技术的优点 观点是提高负载性能,提高恢复能力 能力和审计能力得到提高。的代理键 事实表行是必需的,因为多个相同的主键将 通常存在更新事实行的新旧版本 插入更新行和删除行之间的时间 老排。
- 类似的 ETL 要求是准确确定加载作业被暂停的位置,要么恢复加载,要么完全放回作业。 按顺序分配的代理键使此任务变得简单。
- (来源:
设计提示 #81 事实表代理键
)