为啥事实表中的维度成员集通常用作复合键?

Posted

技术标签:

【中文标题】为啥事实表中的维度成员集通常用作复合键?【英文标题】:Why do the set of dimension members in a fact table are typically used as a composite key?为什么事实表中的维度成员集通常用作复合键? 【发布时间】:2015-05-25 12:58:39 【问题描述】:

根据我的研究,“最佳实践”似乎表明事实表中的一行将有一个由所有维度度量组成的复合键:例如,如果我在事实表中的度量是“销售额”并且我有四个维度:“location、salesperson、buyerCat、salesMonth”然后,我的复合键将包含这 4 个维度的唯一值。但这会导致严重的问题:如果我有两个具有唯一维度集的度量怎么办?

  --Example: Fact table row: 
  Sales Amount: $100, location: US, salesperson: Bob, buyerCat: Young, salesMonth: Feb/2010
  Sales Amount: $640, location: US, salesperson: Bob, buyerCat: Young, salesMonth: Feb/2010 

然后将阻止此度量进入数据集市,因为所有维度成员都被用作复合键。我说的不对吗?

【问题讨论】:

【参考方案1】:

如果您发现这会有问题,那么您可能需要查看您的数据模型并质疑为什么要加载使用完全相同维度的多行。

在您给出的示例中,可能这些实际上是不同的销售。如果是这样,它们可能发生在不同的日期 - 但您只是在月份级别进行记录,因此您丢失了该数据。如果您将确切的日期作为维度包含在内,那么您的重复问题就会消失。或者,如果这两个销售可能在同一天,那么可能有来自销售的交易编号可以记录并用作退化维度 - 同样,您不再有使用相同维度的行。

交易事实表应基于事件(在您的示例中,发生销售)为事物建模,并且它们应引用足够的维度来唯一标识该事件的每个特定事件。

如果您真的不关心将数据保持在最精细的粒度,那么您正在构建的不是事务事实表,而是可能类似于定期快照事实表的东西。在这种情况下,您应该将这两行相加,这样您就只有一行的销售额为 740 美元。

但是,我会非常小心地以这种方式构建仓库,而不是构建下降到最低粒度的事务事实表——即使现在没有人想要报告或分析到那个级别,他们可能以后想要,并且重构您的数据仓库和 ETL 以在较低粒度下工作会很痛苦。然而,如果您首先以尽可能低的粒度创建事务事实表,则您始终可以聚合 - 无论您的用户在 SSAS 等 OLAP 工具中执行此操作,还是您创建一些聚合表或视图以使其更容易用于报告目的。

【讨论】:

非常有趣的答案,非常感谢您向我介绍“退化维度”的概念。不知道是谁投了反对票,但我喜欢这个答案。虽然我会等待更多的答案 @LearnByReading 我猜有人不同意我的观点——如果有什么我可以改进的,最好知道哪个!但是不要紧;很高兴它有所帮助 - 对这些事情有不同的看法当然很好。 投了赞成票,很好的答案:)【参考方案2】:

最好避免使用复合键或任何与业务相关的键来唯一标识事实表行。我可以向您保证,您会找到许多共享相同维度键的记录。使用Kimball website 提供的步骤清楚地定义事实表粒度,您无需担心事实行的唯一性

【讨论】:

我认为您误解了 Kimball 在那篇文章中所说的话:他说示例 Fact 记录可以由 更少 维度唯一标识,而不是与 Fact 相关的维度,而不是您应该期望 Fact 表中的记录具有完全相同的关联维度集。谷物应该是原子的——一个事件。正如 Kimball 所说,你不应该进一步划分它。如果您有重复项,并且您可以添加另一个维度以使它们独一无二,那么数据仍然是可分割的,而不是真正的原子。【参考方案3】:

除非您将复合键定义为唯一的,否则您可以拥有任意数量的重复项。

【讨论】:

嗨,抱歉,我的问题可能不清楚:据我了解,最佳做法是创建一个防止重复的复合键。我的问题是“为什么?”。如果创建复合键,则不能有两个使用完全相同的维度集的值(度量)。在我看来,这似乎是不正确的,那么为什么几乎每个 DW 都是这样设计的呢?

以上是关于为啥事实表中的维度成员集通常用作复合键?的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop之数据仓库设计

Hadoop之数据仓库设计

具有主键和外键的事实表

慢慢改变尺寸

为啥要分出事实表fact和维度表dim

维度的计算成员