避免加入事实表的策略
Posted
技术标签:
【中文标题】避免加入事实表的策略【英文标题】:Strategy to avoid joining fact tables 【发布时间】:2013-12-20 00:12:37 【问题描述】:我的仓库中有三个事实,它们可以是我的关系数据库中的相关事件。它们是PhoneContact、约会和捐赠。 PhoneContact 可以导致约会 和/或捐赠。我已经有了 Apppointment 和 Donation 事实及其相关维度,现在正在将 PhoneContact 添加到我的仓库中。所有这些事实之间的共同维度是捐赠者维度,它描述了谁接到电话并进行了预约和捐赠。
如果 PhoneContact 确实导致了约会和/或捐赠,我想加入这些事实,但我的理解是加入事实是一个禁忌。我将如何最好地关联这些事实?现在我想不出更好的办法,所以我正在考虑将 AppointmentID 和 DonationID 字段放在我的 Phonecontacts 事实中。
更多信息:每月大约有 120 万 PhoneContacts,但其中只有大约 100k 会导致约会或捐赠,所以搁置一边从不加入事实,只是将每月 110 万 NULL
s 放入表中,这样我就可以获得 100K 其他事件似乎不太好。
【问题讨论】:
Appointment
和Donation
表中的行是否总是与PhoneContact
相关?如果是这样,请考虑将问题转为正题 - 从 Appointment
和 Donation
表中创建一个 FK 列到 PhoneContact
。
好问题@Mike。他们不是。可以有 Appointment
或 Donation
而没有 PhoneContact
。
只是我的两分钱:与任何数据仓库一样,我建议提供一个模型,以最大限度地减少对最终用户的意外。尽管Appointment
和Donation
行有时在PhoneContacts
表中有对应的行,但对于您的最终用户来说,稀疏的FK 列可能是最“自然”的解决方案。更规范的解决方案,例如添加多对多表,将消除空值,但它并不真正属于数据仓库。因此,加入事实表可能是您必须选择的弊端中较小的一个。
您回答了自己的问题:您通过捐赠者维度加入了他们。无论如何,您应该在业务问题中表达您的 DW 的要求。什么问题需要加入所有事实?
【参考方案1】:
这里似乎需要在空间和性能之间进行权衡。似乎加入会节省空间。另一方面,如果我们使用非规范化表(已经加入),我们可能会在需要扫描整个表的复杂 group by 查询上获得更好的性能。
请注意,在某些情况下加入可能会更便宜:
如果您的表是根据连接键排序的,连接成本会更低(因为我们将使用合并连接算法)。
如果您的查询产生的行数很少(例如,给我有关 John 的信息),则加入很好的索引将是负担得起的。
如果您认为您的用例始终不属于上述类别,并且您可以轻松购买更多磁盘空间,则创建已连接的表有助于提高查询速度。
【讨论】:
以上是关于避免加入事实表的策略的主要内容,如果未能解决你的问题,请参考以下文章