事实表有多个事实

时间:2010-03-08 20:44:42

标签: sql-server data-warehouse database-schema fact-table

我有一个维度(SiteItem)有两个重要的事实:

perUserClicks 
perBrowserClicks

然而,在这个维度中,我有一组基于属性列的值(让我们调用组AboveFoldItems,LeftNavItems,OnTheFlyItems等)每个都有更多特定于该组的事实:

AboveFoldItems: eyeTime, loadTime
LeftNavItems: mouseOverTime
OnTheFlyItems: doesn't have any extra, but may in the future

以下事实表架构是否正常?

DateKey   
SessionKey
SiteItemKey
perUserClicks 
perBrowserClicks
eyeTime
loadTime
mouseOverTime

这看起来有点浪费,因为只有一些列属于某些维度键(不相关的事实都是NULL)。但是......这似乎是一个常见的问题,所以应该有一个共同的解决方案,对吗?

3 个答案:

答案 0 :(得分:4)

我通常同意Damir对此的回答,但因为事实表在你的特定情况下非常狭窄,所以Aaron保留NULL的建议仍然有用。

我们在特定主题领域有几个星型模式,其中多个事实表共享大多数(如果不是全部)维度(符合和内部)。有限范围的维度在整个企业中不被视为“符合”,但它们就是我们所谓的“共享内部”维度。

现在通常情况下,如果同时加载数据以便维度没有更改,则可以在键上加入两个事实表,但一般情况下,如果维度键上不能连接两个不同的星型模式,他们是传统缓慢变化的维度的代理人。一般情况下,您必须在维度内的自然键或“业务键”上加入单独的星号,而不是在代理项目上(通常在日期维度的特殊情况下,它不变,只有自然键)。

请注意,当你加入这两颗星时,你必须使用LEFT JOIN,在这种情况下你将产生NULL,你仍然可能需要考虑 - 所以你实际上回到原始模型你有NULL! ; - )

额外事实表的好处更明显,当您的表格宽度较小且密钥集较小且数据的垂直分区可节省空间以及更清晰的逻辑模型时 - 尤其如此,当密钥为只有真正共享一点 - 拥有一个虚拟键或NULL键绝对不是一个好主意 - 这通常指向一个维度建模问题。

然而,正如Aaron所说,如果你把它推到极端,你可以在每个事实表中使用共享密钥的单个事实列,这意味着密钥开销使事实成本相形见绌,你真的最终以伪装的EAV结束模型。

我还想看看你是否处于Kimball的“太少维度”的情况。好像你必须具有集中在SessionKey和SiteItemKey中的良好维度属性 - 但是没有看到你的整个模型和要求,很难说,但我认为你会有一些低基数甚至雪花维度的用户人口统计数据,而不是完整的会话或网站维度。

答案 1 :(得分:3)

确实没有一个优雅的解决方案,你要么拥有可以为空的列,要么使用EAV解决方案。我之前发布了关于EAV的信息(并且产生了很多可能值得一读的评论):

在某些情况下,我是该模型的粉丝,但如果你的尺寸/属性不经常变化,那么它可能会带来很多额外的工作。只要周围的代码可以适当地处理它们,列中的NULL值就不会真正浪费。

答案 2 :(得分:1)

你可以拥有多个事实表:factperUserClicks,factperBroWserClicks,factEyeTime等......

每个都有DateKey,SessionKey,SiteItemKey。这样,只有“有意义”的维度键才会出现在每个事实中。

理想情况下,DW中不应该有NULLS - 如果将它们保存在同一个事实表中,使用零可能更合适。

至于节省磁盘空间,我没有看到理想的解决方案 - 但是,在DW中,无论如何都应该交换空间以提高速度和(查询)简单性。