数据仓库中的自定义/动态分类

时间:2013-01-30 19:29:30

标签: sql-server database reporting-services ssas data-warehouse

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

基本上,问题是这个。我们有一个数据仓库,可以跟踪项目。我们必须从这个数据仓库中做很多报告。许多报告都是通过对这些项目进行分类,然后根据分类聚合数据来实现的。某些报告共享分类,有些报告可能有自己的特定于报告的分类。即使在这种情况下,也可能需要重用这些分类的后续报告或分析(ad-hoc)。并且可能会有很多这些分类方案。此外,这些方案可能依赖于来自多个事实表的数据,以便对项目进行分类(并且由于不同的粒度,项目信息跨越多个事实表)。

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

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

  1. 只需将逻辑放入报告和分析查询中,即使这意味着将分类逻辑从查询复制并粘贴到查询
  2. 使用维度方法及其缺陷
  3. 具有计算类别的功能,可以在查询中使用,但成本很高,因为他们可能不得不在其中进行其他查询(性能不佳)
  4. 在包含额外类别列的事实表之上拥有视图;可以比常规表模式更容易地更改视图,并且不需要修改ETL过程
  5. 使用某种桥接表方案在每个类别中的类别和项目之间实现多对多映射;这增加了查询的复杂性,但将方案修改减少到无; ETL仍然需要修改,但修改可能在较小的区域(可能是单个查询或更新类别映射的过程)
  6. 我们希望这个系统是可访问的,这样用户就不需要做太多(如果有的话)访问这些分类字段,就像访问常规事实和维度字段一样。我们还希望每次将新的分类模式添加到数据库时都避免对模式和ETL过程进行大量更改。

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

CategoryID  
Category Name

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

类别 - Dim1映射(CATEGORY_D1)

CategoryID
Dim1ID

类别 - DimX Mapping

CategoryID
DimXID

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

当您构建报表时,您可以在Fact Table,Dim Tables和Category Table之间定义连接。

如果我想找到第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),然后根据它构建映射表。

您的加入会更简单一些 - 只需加入dims&事实上维度键上的类别映射。

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)