避免加入事实表的策略

Posted

技术标签:

【中文标题】避免加入事实表的策略【英文标题】:Strategy to avoid joining fact tables 【发布时间】:2013-12-20 00:12:37 【问题描述】:

我的仓库中有三个事实,它们可以是我的关系数据库中的相关事件。它们是PhoneContact约会捐赠PhoneContact 可以导致约会 和/或捐赠。我已经有了 ApppointmentDonation 事实及其相关维度,现在正在将 PhoneContact 添加到我的仓库中。所有这些事实之间的共同维度是捐赠者维度,它描述了谁接到电话并进行了预约和捐赠。

如果 PhoneContact 确实导致了约会和/或捐赠,我想加入这些事实,但我的理解是加入事实是一个禁忌。我将如何最好地关联这些事实?现在我想不出更好的办法,所以我正在考虑将 AppointmentID 和 DonationID 字段放在我的 Phonecontacts 事实中。

更多信息:每月大约有 120 万 PhoneContacts,但其中只有大约 100k 会导致约会捐赠,所以搁置一边从不加入事实,只是将每月 110 万 NULLs 放入表中,这样我就可以获得 100K 其他事件似乎不太好。

【问题讨论】:

AppointmentDonation 表中的行是否总是与PhoneContact 相关?如果是这样,请考虑将问题转为正题 - 从 AppointmentDonation 表中创建一个 FK 列到 PhoneContact 好问题@Mike。他们不是。可以有 AppointmentDonation 而没有 PhoneContact 只是我的两分钱:与任何数据仓库一样,我建议提供一个模型,以最大限度地减少对最终用户的意外。尽管AppointmentDonation 行有时在PhoneContacts 表中有对应的行,但对于您的最终用户来说,稀疏的FK 列可能是最“自然”的解决方案。更规范的解决方案,例如添加多对多表,将消除空值,但它并不真正属于数据仓库。因此,加入事实表可能是您必须选择的弊端中较小的一个。 您回答了自己的问题:您通过捐赠者维度加入了他们。无论如何,您应该在业务问题中表达您的 DW 的要求。什么问题需要加入所有事实? 【参考方案1】:

这里似乎需要在空间和性能之间进行权衡。似乎加入会节省空间。另一方面,如果我们使用非规范化表(已经加入),我们可能会在需要扫描整个表的复杂 group by 查询上获得更好的性能。

请注意,在某些情况下加入可能会更便宜:

如果您的表是根据连接键排序的,连接成本会更低(因为我们将使用合并连接算法)。

如果您的查询产生的行数很少(例如,给我有关 John 的信息),则加入很好的索引将是负担得起的。

如果您认为您的用例始终不属于上述类别,并且您可以轻松购买更多磁盘空间,则创建已连接的表有助于提高查询速度。

【讨论】:

以上是关于避免加入事实表的策略的主要内容,如果未能解决你的问题,请参考以下文章

在多列上连接大量表的策略?

SQL性能调优策略

优化平衡的策略

策略模式

近实时分析策略

Mysql优化策略