2012-12-17 72 views
3

我们的数据仓库使用来自数据源的累积数据(并且无法反转累积)来创建雪花模式。我们必须解决的一个要求是我们的模式必须可用于根据日期范围创建报告。数据仓库:处理累积数据

我们的模式看起来像这样(简化):

+------------------------------------------+ 
| fact          | 
+-------+-----------------+----------------+ 
| id | statisticsDimId | dateRangeDimId | 
+-------+-----------------+----------------+ 
|  1 |    1 |    10 | 
|  2 |    2 |    11 | 
|  3 |    3 |    12 | 
|  4 |    4 |    13 | 
|  5 |    5 |    14 | 
|  6 |    5 |    15 | 
|  7 |    5 |    16 | 
| ... |    ... |   ... | 
| 10001 |   9908 |    11 | 
| 10002 |   9909 |    11 | 
+-------+-----------------+----------------+ 

+-------------------------------------------------+ 
| date_range_dimension       | 
+-------+-----------------------------------------+ 
| id | startDateTime  | endDateTime  | 
+-------+--------------------+--------------------+ 
| 10 | '2012-01-01 00:00' | '2012-01-01 23:59' | 
| 11 | '2012-01-01 00:00' | '2012-01-02 23:59' | 
| 12 | '2012-01-01 00:00' | '2012-01-03 23:59' | 
| 13 | '2012-01-01 00:00' | '2012-01-04 23:59' | 
| 14 | '2012-01-01 00:00' | '2012-01-05 23:59' | 
| 15 | '2012-01-01 00:00' | '2012-01-06 23:59' | 
| 16 | '2012-01-01 00:00' | '2012-01-07 23:59' | 
| 17 | '2012-01-01 00:00' | '2012-01-08 23:59' | 
| 18 | '2012-01-01 00:00' | '2012-01-09 23:59' | 
| ... |    ... |    ... | 
+-------+--------------------+--------------------+ 

+-----------------------------------------------------+ 
| statistics_dimension        | 
+-------+-------------------+-------------------+-----+ 
| id | accumulatedValue1 | accumulatedValue2 | ... | 
+-------+-------------------+-------------------+-----+ 
|  1 | [not relevant] | [not relevant] | ... | 
|  2 | [not relevant] | [not relevant] | ... | 
|  3 | [not relevant] | [not relevant] | ... | 
|  4 | [not relevant] | [not relevant] | ... | 
|  5 | [not relevant] | [not relevant] | ... | 
|  6 | [not relevant] | [not relevant] | ... | 
|  7 | [not relevant] | [not relevant] | ... | 
| ... | [not relevant] | [not relevant] | ... | 
| ... | [not relevant] | [not relevant] | ... | 
| 10001 | [not relevant] | [not relevant] | ... | 
| 10002 | [not relevant] | [not relevant] | ... | 
+-------+-------------------+-------------------+-----+ 

我们要创建我们的报表数据与这样的设置:

SELECT * 
    FROM fact 
INNER JOIN statistics_dimension 
    ON (fact.statisticsDimId = statistics_dimension.id) 
INNER JOIN date_range_dimension 
    ON (fact.dateDimId = date_range_dimension.id) 
WHERE 
    date_range_dimension.startDateTime = [start] 
AND 
    date_range_dimension.endDateTime = [end] 

的问题是,在我们的统计维度数据已经积累了,我们不能反转积累。我们计算了事实表中近似的行数,得到了5,250,137,022,180。我们的数据大约有250万个日期范围排列,我们需要将它们计算到我们的日期维度和事实表中,因为这些累积。 SQL的SUM函数由于累积而不适用于我们(不能添加属于非不同集的两个值)。

是否有最佳做法,我们可以按照使其计算可行?我们的模式设计有什么问题吗?

我们需要报告有关在线培训的数据。数据源是一个遗留数据提供程序,其部件超过10年 - 因此没有人可以重构内部逻辑。统计维度包含 - 例如 - 用户在基于网络的培训(WBT)中完成的进度(以%计),每个WBT页面的呼叫数量,WBT的状态(对于用户,例如“已完成”) ,aso。关于数据提供者的重要事情是:它只是给我们一个当前状态的快照。我们无法访问历史数据。

+3

您可以在数据背后添加一些业务细节吗?你试图回答什么问题(用商业术语而不是SQL)。我认为这对于更好地了解你的情况会很有帮助。 –

+0

我已经添加了关于上下文的信息。 –

+1

在一个典型的事实表中,这些度量值实际上是在表格上,而不是在另一个维度上。这会大大减慢你的速度。 –

回答

2

我假设你在这方面有一些非常强大的硬件。您的设计有一个主要缺点 - 事实表和“统计”维之间的连接。

通常情况下,事实表包含维度和度量。在我看来,你的“统计”维度和你的事实表之间可能存在1-1的关系。由于事实表本质上是一个“多 - 多”关系表,因此将您的统计信息放在单独的表上是没有意义的。另外,你说统计表有“用户”信息。

无论何时您在仓储中说“按X”,几乎都可以确定X应该是一个维度。

我会看到有关建立你的事实表的直接措施。我不确定你想要用“反转”统计表上的积累来做什么?你的意思是它是在日期范围内累积的?用户?如果数据的不是原子操作,你能做的最好的就是给你有什么...

+0

好吧,好吧。即使我们将统计信息移入事实表,但由于日期范围的原因,我们仍然有大量数据。 –

+0

如果我正确理解你的数据,你会得到一段时间的测量,对吧?如果是这样,那么你将有一个非常大量的数据。如果您发布了正在发送给您的数据示例,这可能会有所帮助,因此我们可以更好地了解您的数据意味着什么已经累积。 –

1

可以减少计算该任务所需的维数:

  • 日常粒度加入时间维度不使用当前的设计
  • 合并与事实表

统计尺寸在我们当前的数据仓库,我们使用以下方法:

time_dimension 
time_key (bigint) 
time_date (date) 
(other time related columns) 

fact_table 
(keys to other dimensions) 
time_key_start (bigint) /* reference to time_dimension, time_key */ 
time_key_end (bigint) /* reference to time_dimension, time_key */ 
value_1 
value_2 

此外,time_dimension中的键是“智能”。我知道很多人都不会这样的设计一致,但在性能还有待提高,我们可以通过直接查询time_key,与像条件减少查询中使用的维数:

time_key_start = to_char('2012-01-01','J')::bigint 
and 
time_key_end = to_char('2012-01-02','J')::bigint 

有了这样的设计,你可以避免查询中的所有连接。然后,您必须关注表分区和索引以提高性能。

也许,也不需要分析数据的整个历史记录,并且可以将一些数据移动到归档。