标题和订单项数据源不匹配

Dus*_*gen 7 data-warehouse sql-server facttable

我正在使用数据仓库的星型模式,但遇到来自不同数据源的标题和行项目的问题。

CREATE TABLE DataSourceAHeader
(
     OrderId INT NOT NULL
    ,TotalCost MONEY NOT NULL
    -- Date, etc...
);

CREATE TABLE DataSourceALine
(
     OrderId INT NOT NULL
    ,LineNumber INT NOT NULL
    -- Dates, etc...
);

CREATE TABLE DataSourceBLine
(
     OrderId INT NOT NULL
    ,Cost MONEY NOT NULL
    ,LineNumber INT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

我有数据源 A 和 B,它们以不同的方式表示相同的数据。数据源 A 包含标题和行项目,但标题中仅包含净结果(总成本)。数据源 B 仅包含行项目,每个项目都有一个结果(成本)。

我可以保留两个事实表(一个用于标题,一个用于行项目),但我已经研究过,这似乎是不可取的。是否有处理这种不匹配格式的策略,还是应该将它们存储在单独的数据仓库中(每个数据源一个仓库)?

我目前的策略:

CREATE TABLE Fact.Order
(
     Id BIGINT IDENTITY PRIMARY KEY
    ,OrderId INT NOT NULL
    ,Cost MONEY NOT NULL
    -- Date key, etc...
);

CREATE TABLE Fact.OrderLine
(
     Id BIGINT IDENTITY PRIMARY KEY
    ,OrderFactId BIGINT NOT NULL REFERENCES Fact.Order (Id)
    ,LineNumber INT NOT NULL
    -- related line stuff
);
Run Code Online (Sandbox Code Playgroud)

DataSourceAHeader并且DataSourceBLine被插入到Order和 中OrderLineDataSourceBLine每行拆分一行。

这是一个DataSourceAHeader和的例子DataSourceALine

SELECT * FROM Fact.Order;
|------------------------------------|
|   Id   |   OrderId   |   Cost      |
|   1    |     1100    |   12000.00  |
|   2    |     1101    |   10000.00  |
|------------------------------------|

SELECT * FROM Fact.OrderLine;
|-------------------------------------------|
|   Id   |   OrderFactId   |   LineNumber   |
|   1    |        1        |       1        |
|   2    |        1        |       2        |
|   3    |        1        |       3        |
|   4    |        2        |       1        |
|   5    |        2        |       2        |
|   6    |        2        |       3        |
|-------------------------------------------|
Run Code Online (Sandbox Code Playgroud)

这是一个例子 DataSourceBLine

SELECT * FROM Fact.Order;
|---------------------------------|
|   Id   |   OrderId   |   Cost   |
|   1    |     1000    |   12.00  |
|   2    |     1000    |   10.00  |
|---------------------------------|

SELECT * FROM Fact.OrderLine;
|-------------------------------------------|
|   Id   |   OrderFactId   |   LineNumber   |
|   1    |        1        |       1        |
|   2    |        2        |       2        |
|-------------------------------------------|
Run Code Online (Sandbox Code Playgroud)

编辑:

TotalCost在报头不能被放倒在线路电平。我与一位架构师熟人聊天,他的建议是实现两个单独的事实表,一个用于标题(摘要),一个用于行(详细信息),并且只NULLDataSourceA.

编辑2:

我正在尝试使用 OrderId 通用,因为我还有几个数据源可能包含类似的 OrderId 方案(冲突)。我已经实现了一个映射表,以便将源标识符转换到仓库中。

编辑3:

为了让这个问题不仅仅对我自己有帮助,我希望答案具有以下详细信息(主要是为了汇编每个人已经推理过的内容):

  • 一般来说,解决采用汇总/详细信息(单个事实表或汇总/详细事实表)形式的相关不相交数据集的方法是什么?
  • 每种方法的缺点是什么?
  • 事实表可以采用什么样的结构来处理缺失(或不相关)的数据?
  • (两个事实表方法)在什么情况下,滚动汇总与汇总细节比较谨慎?

Mat*_*att 4

如果您想将其非规范化为单个事实表,则该事实表将与行项目有关。因此,来自 DataSourceAHeader 的事实需要拆分并分发到相关的行项目,这样它们就不会重复。正如目前所呈现的,这意味着降低总订单成本并通过对行项目成本求和来计算。

\n\n

DataSourceAHeader 维度键(例如订单日期)可以从DataSourceAHeader 中获取并应用于从DataSourceBLine 生成的事实行。在示例中,DataSourceALine 上似乎不包含尚未包含在 DataSourceAHeader 或 DataSourceBLine 中的任何信息,但如果存在,则可以以类似的方式进行映射。

\n\n

这种方法依赖于许多假设,其中关键的一个是 DataSourceAHeader 中的所有事实都可以准确地分布在其组成的行项目中。如果情况并非如此,加载两个单独的事实表(一个用于订单,一个用于行项目)可能是更好的方法。如果需要询问很多有关订单的问题,而这些问题不考虑订单项的特定信息,则情况可能也是如此。这在您引用的文章中被标记为“坏主意#2”,但我发现在某些情况下,这实际上是一个好主意。

\n\n

最后,这假设两个数据源是同步的。如果不是,您将限制自己以较慢的数据源的速度加载数据。这可能没问题,但需要根据您的需求以及两个数据源之间的差异进行考虑。

\n\n

编辑:反规范化为单个事实表可能会在计算订单时显着影响性能,因为它本质上是一个不同的计数,这将是我考虑两个单独的事实表的主要原因。

\n\n

编辑2(回应问题编辑):

\n\n

这里的问题是,在最细粒度的级别(行)数据是不完整的,因为并非所有行都有成本值。但是,总成本信息可在上一级(标题)中获得。\n这表明您无法从较低级别推导出较高级别;让\xe2\x80\x99s 考虑结果选项:

\n\n
    \n
  1. 拥有可用的最低粒度(行)的单个事实表。这是不可能的,因为我们现在依靠不完整的线路数据来回答更高级别的问题,我们知道我们可以回答这些问题。
  2. \n
  3. 有一个更高粒度的事实表(表头)。这意味着我们现在可以用完整的数据回答更高级别的问题,但根本无法再回答更细粒度的问题。这可能被认为是可以接受的,但在大多数情况下我们会丢弃潜在有价值的数据。
  4. \n
  5. 有两个相关的事实表,一张用于不完整的、更精细的数据(行),一张用于完整的、不太精细的数据(标题)。这是理想的解决方案,因为我们现在可以完整回答较高级别的问题,并且可以在源数据不完整的情况下对较低级别的问题给出最佳答案。
  6. \n
\n\n

提出这个问题是因为对两个相关的事实表存在疑问。怀疑源于这样一个事实:维护和连接两个大型事实表可能会占用大量资源。确实如此,如果可以使用最精细的信息来提供情况的完整描述,那么最好使用单个事实表。但是,在这种不可能的情况下,如果您想保留尽可能多的信息,则需要两个事实表。

\n