数据库设计 – 如何避免星型模式中事实表之间的连接?

我正在尝试使用星型模式来建模我的数据仓库,但我有一个问题是要避免事实表之间的连接.

为了解决我的问题,我想收集操作系统上发生的所有事件.因此,我可以创建一个事件表事件,其中包含一些维度,如datetime或user.问题是我想收集不同类型的事件:硬件事件和软件事件.

问题是那些事件的维度不同.例如,对于硬件事件,我可以拥有physical_component或related_driver维度,对于软件事件,可以使用software_name或online_application维度(这只是一些示例,要记住的事实是事件可以专门用于某些特定事件具体尺寸).

在关系模型中,我将有3个表组织如下:

《数据库设计 – 如何避免星型模式中事实表之间的连接?》

问题是:如何处理星型模式中事实表之间的连接?

我想象了4个想法,但我不确定其中一个是否适合这种情况.

第一个是保持关系数据库中使用的模型,并添加如下维度表:

《数据库设计 – 如何避免星型模式中事实表之间的连接?》

在这种情况下,问题是我们仍然在事实表之间连接,并且需要在我们的所有查询中使用JOIN SQL语句.

第二个是仅创建2个将复制共享维度(日期时间和用户)的事实表,并创建汇总所有事件的物化视图事件:

《数据库设计 – 如何避免星型模式中事实表之间的连接?》

这里的问题是:如果我想在物化视图上进行查询会发生什么?根据我在Oracle文档中读到的内容,我们不必直接在物化视图上进行查询,但我们必须让查询重写过程才能使其工作.
第三个是仅创建一个事实表,其中包含事件(硬件或软件)可能的所有信息:
《数据库设计 – 如何避免星型模式中事实表之间的连接?》
这个时候,问题是我的事实表会包含很多NULL值.
最后一个是创建3个事实表(这次没有物化视图),如下所示:
《数据库设计 – 如何避免星型模式中事实表之间的连接?》
这一次,问题是事实表事件和它自己的表中都存在所有事件.因为我们将存储大量数据,所以我不确定这种重复是一个好主意.

那么什么是最好的解决方案?或者它是否存在第五种解决方案?

最佳答案 从您的描述和随后的评论到其他答案,我会说选项2或选项4是从维度建模角度对事物进行建模的正确方法.每个事实应该是业务流程的衡量标准,软件和硬件事件的维度似乎是完全不同的,它们需要单独存储.

然后,还有一种情况是将单独的事件表存储为视图,物化视图或存储常见事物的普通表.

一旦你确定这是“逻辑”模拟事物的正确方法,那么你需要平衡性能,可维护性,可用性和存储.
对于维度建模,查询的可用性和性能是最重要的(否则您可能根本不使用维度模型),ETL中的额外工作以及所需的额外空间是值得付出的代价.

非物化视图会以性能价格为您节省空间,但可能是您可以为其提供足够强大的索引或两个可以缓解这一点的索引.物化视图将以存储价格为您提供性能.

我很想用索引和非物化视图创建两个事实表,并在进一步提高性能之前看看它的性能是什么样的. 1000万个事实行并没有那么糟糕,它仍然可以执行.

可以直接查询物化视图.但是,如果您愿意,可以使用Oracle的查询重写功能,以便在查询原始表时,将Materialized视图用作性能增强器,如索引.
有关详细信息,请参见此处:http://www.sqlsnippets.com/en/topic-12918.html
无论您选择在查询重写模式中使用它还是仅作为视图使用它取决于您是否希望用户知道这个额外的表,或者只是作为一个有用的朋友坐在后台.

点赞