将层次结构放在其自己的单独维度中还是将其设置为相关维度的一部分?

Posted

技术标签:

【中文标题】将层次结构放在其自己的单独维度中还是将其设置为相关维度的一部分?【英文标题】:Put hierarchy in its own separate dimension or set it as a part of related dimension? 【发布时间】:2020-12-27 17:24:54 【问题描述】:

我是 the dimensional model 的数据仓库设计新手,在我的第一个设计中遇到了一些困惑。

我做一个简单的业务流程(Vacation Request),请问这两种设计中哪一种是准确和接近有效和适用的,如果我能得到详细的答复,我将不胜感激? (我的问题主要是关于尺寸设计)

1- 

Dimension.Employee           Fact.Vacation
[Employee Key]               [Employee Key] FK PK
[_source key]                [Vacation Transaction]PK DD
[Employee Name]              ...
....                         ...
[Campus Code]
[Campus Name]
[Department Code]
[Department Name]
[Section code]
[Section Name]
.... 

2- 

Dimension.Employee           Dimension.Section         Fact.Vacation
[Employee Key]               [Section Key]             [Employee Key] FK PK
[_source key]                [_source key]             [Vacation Transaction]PK DD
[Employee Name]              [Department Code]         [Section Key]FK
....                         [Department Name]         ...
....                         [Campus Code]
                             [Campus Name]

层次结构是这样的:

Campus Contains --> 
Many Departments and each department contains --> 
many sections and each section contains many employees

【问题讨论】:

【参考方案1】:

好问题!我自己也多次遇到过这种情况。恐怕这会有点令人困惑,最终的答案将是“视情况而定”,但这里有一些需要考虑的事情......

星型模式的真正含义:虽然人们将数据仓库视为报告数据库,但它实际上执行两个功能:数据集成和数据分发。事实证明,用于集成的最佳数据结构并不适合分发(这是我几年前写的blog post)。星型模式实际上是关于数据分布 - 快速轻松地将数据从系统中取出。最好的数据结构没有连接,即它们类似于平面文件(是的,我意识到有一些 DB 缓冲考虑可能会影响这一点,但一般来说,索引平面文件确实避免了所有连接)。

星型模式采用该平面文件并将其标准化一点,主要是为了节省磁盘空间(当您必须在每条记录上写出每个维度的每个属性时,这是一个巨大的空间浪费)。因此,当人们说星型模式是非规范化的时,他们是部分不正确的。维度表是非规范化的(雪花模式对这些进行规范化),但事实表是规范化的——它有一堆依赖于唯一主键的属性。

因此,这个概念将指向最小化维度的数量,以最小化您需要进行的连接数量。将它们放入一维的点。

事实表显示关系:您的事实表显示其他不相关的维度元素之间的关系。例如,在没有销售的情况下,产品和客户之间没有任何关系。销售创建了这种关系,销售事实记录对其进行建模。就您而言,部门和员工之间存在自然关系(至少我假设)。您不需要事实表来为这种关系建模,因此,它们都应该在一个维度表中。将它们放入一维的另一点。

一个员工可以同时在多个部门吗?:如果一个员工可以同时在多个部门,那么您可能确实需要事实表来为这种关系建模(否则,每个员工都需要员工中有两条活动记录尺寸表)。将它们放入单独的维度的要点。

员工是否经常更改部分?:如果是这样,并且您只有一个维度,您最终将不得不不断修改员工维度中的员工记录 - 如果这是,这会导致比需要更长的维度表第二类缓慢变化的维度(即您正在跟踪维度元素更改历史的维度)。将它们放入单独的维度的要点。

您是否需要按部分汇总?:如果您有很多部分并且经常在部分级别报告,您可能需要创建在部分级别汇总的事实表。在这种情况下,如果您坚信让您的数据库强制执行您的关系(我是),您将需要一个与事实表相关的节表。在这种情况下,您将需要一个节表。将它们放入单独的维度的要点。

其他事实表是否会使用部分维度?:当您使用一致的维度(即由多个事实表共享的维度)时,星型模式会出现一种棘手的情况。当在维度层次结构中的不同级别定义不同的事实表时,就会出现问题。在您的情况下,假设有一个不同的事实表,比如购买了一个建模设备,它只在部门而不是员工级别有意义。在这种情况下,您可能会将部分维度拆分为它自己的表,以便它可以由两个事实表共享,您当前的表和未来的设备表。顺便说一句,这类似于前面提到的与聚合表相关的考虑。将它们放入单独的维度的要点。

无论如何,这不是我的想法。所以,我想答案是,“这取决于”。两者都可以,它只取决于您尝试优化的其他因素。如果有其他想法,我会尝试编辑我的答案。祝你好运!

【讨论】:

非常感谢您的解释,但是请问您的规则1和其他一些规则适用于我的案例是否存在冲突因素!那么我应该安全地选择哪个场景呢? 我的荣幸!你能提供更多细节吗?您预计会有哪些冲突?最终,如果一种方法不起作用,那么您最好使用另一种方法,而不是强行采用糟糕的解决方案。如果它们都不能很好地工作,也许你需要一些完全不同的东西。 似乎两者都适合你(我对星型模式的一个问题是它们的设计可能非常主观)。你可以对一个维度做的任何事情都将通过将它们分解为多个维度来实现。问题是架构师随机创建维度(最终,您可以将每个字段放入自己的维度中),从而进行连接。如果您经常按部分报告休假请求,那么我可能会将其分解为一个单独的维度。但是,如果您通常处于员工级别,并且部分仅描述员工,我可能会将它们放在一个中。 我想是的。事实上,我正准备在我的回答中添加另一个考虑因素,如果我的解释正确,请解决这一点。 有趣的地方。如果人们在不使用事实表的情况下查询员工维度(例如,按部分显示员工数量),那么您需要这样做(假设您没有将所有内容都保留在一个维度中)。或者,您可以创建一个新的事实表,将员工与每天拍摄的快照联系起来——纯粹主义者可能会建议这样做,但这对我来说似乎是很多不必要的工作。关于合同,您是指合同工吗?他们是否与普通员工具有相同的属性?如果是这样,那么我可能会把它们放在那里。但是,他们甚至有假期吗?【参考方案2】:

第二个。

员工是 WHO,部门是 WHERE。

【讨论】:

以上是关于将层次结构放在其自己的单独维度中还是将其设置为相关维度的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

将字符串转换为对象层次结构

切换标签栏项目时,UINavigationController 如何将其整个视图控制器表示层次结构保存在内存中?

如何将轮廓层次结构从 python openCV 转换为 emgu cv 以查找封闭轮廓

如何将具有父/子层次结构的数据框转换为在单独列中具有父名称的数据框?

什么是处理维度表中层次结构的好方法

更改 Cube 维度的默认层次结构