2012-12-17 101 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 

有了這樣的設計,你可以避免查詢中的所有連接。然後,您必須關注表分區和索引以提高性能。

也許,也不需要分析數據的整個歷史記錄,並且可以將一些數據移動到歸檔。