2011-03-18 83 views
2

我正在尋找擴展積分排行榜系統的建議。我已經有一個使用非常規化策略的工作版本。這第一個版本本質上是一張看起來像這樣的表格。使用SQL Server設計可擴展積分排行榜系統

 
UserPoints - PK: (UserId,Date) 
+------------+--------+---------------------+ 
| UserId  | Points | Date    | 
+------------+--------+---------------------+ 
| 1   | 10  | 2011-03-17 07:16:36 | 
| 2   | 35  | 2011-03-17 08:09:26 | 
| 3   | 40  | 2011-03-17 08:05:36 | 
| 1   | 65  | 2011-03-17 09:01:37 | 
| 2   | 16  | 2011-03-17 10:12:35 | 
| 3   | 64  | 2011-03-17 12:51:33 | 
| 1   | 300 | 2011-03-17 12:19:21 | 
| 2   | 1200 | 2011-03-17 13:24:13 | 
| 3   | 510 | 2011-03-17 17:29:32 | 
+------------+--------+---------------------+ 

然後我有一個存儲過程,它基本上做一個GroupBy用戶ID和總和點。我還可以傳遞@StartDate和@EndDate參數來創建特定時間段的排行榜。例如,針對日/周/月/生命週期的頂級用戶的時間窗口。

這似乎適用於適量的數據,但事情變得明顯慢點的記錄數超過一百萬左右。我正在使用的測試數據是由約500名用戶在3個月的時間內分發的超過100萬個記錄。

有沒有不同的方法來解決這個問題?我已經通過將點預先分組爲小時日期時間桶來減少行數來試驗反規範化數據。但是我開始認爲我需要擔心的真正問題是需要在排行榜中佔據越來越多的用戶。時間窗口的大小通常很小,但越來越多的用戶會在任何給定的窗口內開始生成點。

不幸的是,由於我使用SQL Azure並且代理不可用(尚未),因此我無法訪問'作業'。但是,如果您足夠令人信服,我願意使用不同的存儲系統來擴展這一點。

我過去的工作經驗告訴我,我應該研究數據倉庫,因爲這幾乎是一個報告問題。但同時我需要它儘可能實時。

更新

最後,我想支持,可以從週一早上8點跨越定義的排行榜 - 週五下午6點每星期。但是,這正在走下坡路,爲什麼我不想過分喜歡聚合。現在我願意和基本的日/周/月/年/全時窗一起解決。

棘手的部分是,我真的不能存儲它們的非規範化,因爲我需要這些窗口是TimeZone可兌換。系統是多租戶的,因此所有數據都以UTC格式存儲。問題是一個星期開始於不同客戶的不同時間。彙總在一起會導致一些點落入錯誤的桶中。

回答

0

我決定去與時間跨度一起存儲點(起始日期日期和結束日期列的想法)本地化到客戶當前的TimeZone設置。我意識到一個額外的好處,那就是我可以在幾次比賽之後「清除」舊的排行榜循環數據,而不會影響點的總生命週期。

3

這裏有幾個想法:

  1. 與SQL Azure的堅持:你可以有另一個表,PointsTotals。每次向UserPoints表中添加一行時,也會爲PointsTotals中給定的UserId增加TotalPoints值(或者如果沒有要增加的行,則插入一個新行)。現在您總是爲每個UserId計算總計。
  2. 使用Azure表存儲:創建UserPoints表,分區鍵爲userId。這可以將用戶的所有積分行保存在一起,您可以輕鬆地將它們彙總在一起。而且......你可以借用建議#1的想法,創建一個單獨的PointsTotals表,其中PartitionKey是UserId和RowKey可能是總點數。
+0

我其實已經有了'PointsTotal',但這不是問題。我需要能夠在任何時間段創建用戶排行榜。 (2月1日 - 2月28日)當試圖爲特定日期範圍內的500多個用戶訂購點時,表格存儲無法正常工作。 – Vyrotek 2011-03-18 02:46:05

+0

它是否真的必須用於*任何*日期範圍,或僅僅是某個日/月/周?即從2月3日至4月6日運行一個查詢,您需要快速運行? – knightpfhor 2011-03-18 04:29:35

+0

@knightpfhor - 查看我的更新 – Vyrotek 2011-03-18 04:55:15

0

如果它是我的問題,我會忽略時間戳和白天存儲用戶和點總數