Database design 数据仓库中的事实表是否需要代理主键?

Database design 数据仓库中的事实表是否需要代理主键?,database-design,business-intelligence,Database Design,Business Intelligence,当我问DB设计人员为什么事实表没有PK时,我被告知表中没有一组列可以唯一标识记录,即使所有列都被选中。当我建议我们在这种情况下设立一个身份专栏时,我被告知“我只是在浪费空间,不需要。” 我的感觉是源系统中的每个表都应该有一个PK,即使它是一个标识列。鉴于数据仓库(DW)是来自其他系统的数据接收者,如果无法关联单个记录,我如何才能确保DW中的数据准确反映源系统中的数据?如果你有一个失控的加载程序,它会把数据搞砸,并且已经运行了一周,如果没有某种独特的约束进行比较,您将如何协调与实时事务源系统的差异

当我问DB设计人员为什么事实表没有PK时,我被告知表中没有一组列可以唯一标识记录,即使所有列都被选中。当我建议我们在这种情况下设立一个身份专栏时,我被告知“我只是在浪费空间,不需要。”


我的感觉是源系统中的每个表都应该有一个PK,即使它是一个标识列。鉴于数据仓库(DW)是来自其他系统的数据接收者,如果无法关联单个记录,我如何才能确保DW中的数据准确反映源系统中的数据?如果你有一个失控的加载程序,它会把数据搞砸,并且已经运行了一周,如果没有某种独特的约束进行比较,您将如何协调与实时事务源系统的差异?

没有主键的数据库表似乎是一个糟糕的设计选择,并为不同类型的异常留出了很大的空间,即,您将如何删除或更新此类表中的单个记录?

您是正确的--排序属于如果没有主键,表就不符合关系的最低定义。作为一个关系,最基本的是它不能允许重复的行。数据仓库设计中的表应该是关系表,即使它们不是严格的标准形式

因此,行中必须有一些列(或一组列)用于唯一地标识行。但它不一定是代理密钥的标识列

如果事实表中没有一组列可以充当候选键的角色,那么该DW中需要更多维度表,事实表中需要更多列


这个新维度本身可能不是主键;它可以与事实表中的现有列组合以创建候选键。

我同意您的看法

“我被告知表中没有唯一标识记录的列集,即使选择了所有列。”-这似乎打破了我对关系数据库的理解

事实由加法值加上标注外键组成。时间是一个明显的维度,我所知道的每个维度模型都有这个维度。如果没有其他内容,那么包含时间戳的复合键肯定是唯一的


我想知道你们的DBA是否有很多关于维度建模的知识。这是一种不同于普通关系型、事务型的思维方式。

标识类型列是一个“代理”键,它取代了一个“候选”键(简单地说)。如果您无法识别没有代理键的行,则添加代理键列不会添加任何内容。它需要一个候选键。

数据仓库不一定是关系数据存储,尽管您可以选择将其设置为关系数据存储,因此关系定义不一定适用

只有当您想对需要唯一标识符的数据执行某些操作时,才需要主键(例如,将其跟踪到源,但这并不总是必需的、不必要的,甚至不可能);数据仓库中的数据通常可以不需要主键的方式使用。具体来说,您可能不需要将行彼此区分开来。通常用于构造聚合值

在构造数据仓库表时,时间不是必需的维度


这在心理上可能会让人不舒服,浪费空间是一个微不足道的问题,但你的同事是正确的——PKs是不必要的。

没有每行的唯一标识符比最初看起来更糟糕。当然,这是不稳定的,很容易在不经意间删除一些行

但表现也差得多。每次您要求数据库获取员工
EmployeeType='Manager'
的行时,您都在进行字符串比较。标识符只是更快更好


此外,存储是廉价的,在这种情况下,我想如果这样的话,对空间的影响将不到四分之一个百分点——作为一个数据仓库,您可能正在为TB的数据设计。

如果事实表位于星型模式的中心,那么实际上存在一个候选键。如果将事实表中的所有外键(指向维度表中的行的外键)放在一起,这就是候选键


将其声明为主键可能没有多大好处。它唯一能做的就是保护您免受流氓ETL过程的攻击。管理仓库的人员可能已经掌握了ETL处理

就索引和查询速度而言,星型模式的问题与面向OLTP的数据库完全不同。管理仓库的人可能也有这一点

在设计用于OLTP的数据库时,使用没有主键的表是不明智的。同样的考虑因素不会带入仓库。

寓言: 事实表的主键由所有引用的维度外键组成

事实:
事实表通常有10个或更多外键连接到维度表的主键。但是,行唯一性通常只需要事实表外键引用的一个子集。大多数事实表都有一个主键,该主键由外键的连接/组合子集组成

我一直认为表应该按最常见的查询或性能指标排序,因此表的聚集索引应该与最困难或最常见的查询一致

主键不必是聚集索引,因此我知道您可能想知道我将如何使用它,但我更关心的是聚集索引而不是主键(老实说,它们通常是相互跟随的)

所以