5

我有一个维度(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)。但是……这似乎是一个普遍的问题,所以应该有一个共同的解决方案,对吧?

4

3 回答 3

4

我通常同意 Damir 对此的回答,但由于在您的特定情况下事实表非常狭窄,因此 Aaron 主张保留 NULL 仍然是值得的。

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

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

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

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

然而,正如 Aaron 所说,如果你把它推到极端,你可以在每个事实表中拥有一个带有共享键的事实列,这意味着密钥开销使事实成本相形见绌,并且你确实最终会得到一个伪装的 EAV 模型。

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

于 2010-03-08T23:56:07.057 回答
3

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

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

于 2010-03-08T20:58:45.600 回答
1

您可以拥有多个事实表:factperUserClicks、factperBroWserClicks、factEyeTime 等...

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

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

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

于 2010-03-08T23:05:46.607 回答