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