2

我们正在扩展我们的数据仓库,我们遇到了团队中没有人能够解决的难题。我尝试在 Google 上搜索答案,但很难找到正确的条款。

本质上,问题是这样的。我们有一个跟踪项目的数据仓库。我们必须在这个数据仓库之外做很多报告。许多报告都是通过对这些项目进行分类,然后根据分类汇总数据来驱动的。有些报告共享分类,有些可能有自己的特定于报告的分类。即使在这种情况下,也可能存在需要重用这些分类的后续报告或分析(临时)。并且可能会有很多这样的分类方案。此外,这些方案可能依赖来自多个事实表的数据来对项目进行分类(并且项目信息由于粒度不同而跨越多个事实表)。

我们最初的计划是为这些设置维度,每个类别都有一个维度,或者可能是每个类别都有一个列的垃圾维度。如果分类的数量可能保持不变,那就没问题了。但是,总会有新的报告和分析需求。我们不希望每次想要添加新的分类方案时都必须更改架构和 ETL 过程。我们可能还想更改分类的逻辑,而不必重新导入数据或重新运行 ETL 的一部分来重新计算。

所以我们的选择似乎如下:

  1. 只需将逻辑放在报告和分析查询中,即使这意味着在查询之间复制和粘贴分类逻辑
  2. 使用有缺陷的维度方法
  3. 具有计算类别的函数,可以在查询中使用,但代价高昂,因为它们可能必须在其中执行额外的查询(性能不佳)
  4. 在包含额外类别列的事实表之上拥有视图;视图可以比常规表模式更容易更改,并且不需要修改 ETL 过程
  5. 使用某种桥接表方案来实现类别和每个类别中的项目之间的多对多映射;这增加了查询的复杂性,但将方案修改减少到无;ETL 仍需要修改,但修改可能在较小的区域内(可能是单个查询或更新类别映射的过程)

我们希望这个系统是可访问的,这样用户就不需要像访问常规事实和维度字段那样做更多的事情来访问这些分类字段。我们还希望避免每次将新的分类模式添加到数据库时都必须对模式和 ETL 过程进行大量更改。

所以我的问题是,基本上,有没有比我列出的五个更好的方法可以用来解决这个问题?这五个方面是否有更有效地解决问题的变化?或者它只是一个需要一定程度痛苦的难题?也许我对这一切都错了,所以这方面的任何反馈也会有所帮助。

tl;dr:我们需要在数据仓库中对项目进行许多不同分类的方法,并且不确定最有效、易于管理或易于使用的系统。

编辑:附加信息:我们使用 SQL Server,SSRS 作为主要报告前端,SSAS 作为分析或临时查询的辅助前端。

4

1 回答 1

2

根据上面评论中的讨论,您最好的选择可能是构建一个小的 .NET 应用程序或 Web 应用程序,允许用户根据维度属性自行定义分类。

您可以在“类别表”中定义类别

CategoryID  
Category Name

然后,您将构建一组“映射”表,这些表必须从每个维度创建一个雪花到一个类别:

类别 - Dim1 映射 (CATEGORY_D1)

CategoryID
Dim1ID

类别 - DimX 映射

CategoryID
DimXID

您的小应用程序将在定义类别时维护和构建这些映射表。

然后,当您构建报告时,您定义了事实表、维度表和类别表之间的连接。

如果我想找到第 3 类中的所有项目,那么我会写:

SELECT * 
FROM ITEMS_FACT F
JOIN DIM1 D1 ON (F.DIM1_ID = D1.DIM1_ID)
JOIN CATEGORY_D1 CD2 ON (CD2.DIM1_ID = D1.DIM1_ID 
                         AND CD1.CATEGORY_ID = 3)
JOIN DIM2 D2 ON (F.DIM2_ID = D1.DIM2_ID)
JOIN CATEGORY_D2 CD2 ON (CD2.DIM2_ID = D1.DIM2_ID 
                         AND CD2.CATEGORY_ID = 3)

这将允许用户定义他们想要的任何类别,并且根本没有 ETL 更改(除非您有 SCD 类型 2 - 您可能需要在更新行时应用类别)。

如果存在管理“异常”的类别,您可能需要构建一个类别映射表,其中包含所有暗淡组合:

CategoryID
Dim1ID
Dim2ID
Dim3ID

然后,您可以让用户在他们的工具中定义逻辑(如果 Item 具有 Dim1 Attr2 = 'A' 和 Dim2 Attr3 = 'B' 则类别 1),然后基于此构建映射表。

那么你的加入会更简单一些 - 只需将维度和事实加入维度键上的类别映射即可。

SELECT * 
FROM ITEMS_FACT F
JOIN DIM1 D1 ON (F.DIM1_ID = D1.DIM1_ID)
JOIN DIM2 D2 ON (F.DIM2_ID = D2.DIM2_ID)
JOIN CATEGORY_MAP CM ON (D1.DIM1_ID = CM.DIM1_ID 
                         AND D2.DIM2_ID = CM.DIM2_ID
                         AND CD1.CATEGORY_ID = 3)
于 2013-02-04T16:23:30.887 回答