2009-07-02 82 views
0

這是問題。(ASP.NET)如何創建跟蹤數據庫更改的實時計數器?

在我最近接管的一個網站上追蹤了一天中跑過的「英里數」。因此,用戶可以登錄該網站,添加他們跑了5英里。然後將其添加到數據庫中。

在一天結束時,大約凌晨1點,一個服務運行,計算所有里程,所有用戶在當天運行並輸出一個文本文件到App_Data。該文本文件然後在主頁上閃爍顯示。

我覺得這有點荒謬。我被告知他們必須這樣做,因爲大量的性能問題。他們不會確切地告訴我他們之前是如何做的,或者主要的性能問題是什麼。

那麼你們會採取什麼樣的方法?我首先想到的是一個通過AJAX調用獲取數據的Web服務。也許每次添加新的「英里」條目時,會觸發一個觸發器並更新「GlobalMiles」表。

我會很感激任何關於此的信息或提示。

非常感謝!

回答

1

回答這個問題有點困難,因爲我們不知道所有的需求,而且之前沒有任何工作。所以這裏有一些不同的想法。

首先,重新審視你的假設。如果您需要的只是日常報告,那麼每天生成一次靜態報告是非常有效的解決方案。如果所有需要的都是快照,爲什麼要在數據庫中多次訪問數據庫(例如,當發佈博客時,大量博客軟件用於編寫html文件,而不是每次都從數據庫提供條目 - 許多仍然會作爲優化)。您正在添加的是「實時」功能嗎?

我不會立即跳到AJAX。使用相同的輸入法,只需將報告從靜態移動到動態。立即做太多是讓自己埋葬的好方法。在更改現有代碼時,我嘗試找到可以對應用程序的其餘部分產生最小影響的獨立更改區域。然後,一旦你有動態報告,那麼你可以添加AJAX(並請使用progressive enhancement)。

至於動態報告本身,你有幾個選項。

當然,您可以只選擇SUM(),但聽起來像這樣會導致性能問題,如果每個用戶有大量的條目。

如果您的數據庫支持它,我會看看使用indexed view(有時稱爲物化視圖)。它應該支持允許快速更新,實時和數據:

CREATE VIEW vw_Miles WITH SCHEMABINDING AS 
SELECT SUM([Count]) AS TotalMiles, 
COUNT_BIG(*) AS [EntryCount], 
UserId 
FROM Miles 
GROUP BY UserID 
GO 
CREATE UNIQUE CLUSTERED INDEX ix_Miles ON vw_Miles(UserId) 

如果該開銷太大,@ jn29098的解決方案是一個很好的一次。使用計劃任務捲起它。如果每個用戶有很多條目,則只能添加上次運行任務時的增量。

UPDATE GlobalMiles SET [TotalMiles] = [TotalMiles] + 
    (SELECT SUM([Count]) 
    FROM Miles 
    WHERE UserId = @id 
     AND EntryDate > @lastTaskRun 
    GROUP BY UserId) 
WHERE UserId = @id 

如果你不關心存儲的各個條目,但只有總,你可以在飛行中更新計數:

UPDATE Miles SET [Count] = [Count] + @newCount WHERE UserId = @id 

您可以結合使用此方法與添加存儲過程入口和兩個世界。

最後,你的觸發方法也可以。它是索引視圖的一種替代方法,您可以在SQL自動執行更新的表上進行更新。它也與之前的選項類似,將全局更新從sproc移到觸發器。

最後三個選項使刪除條目時處理情況更加困難,但如果這不是應用程序的功能,那麼您可能不需要擔心這一點。

既然您已經在數據庫中獲得了實體化的實時數據,現在您可以動態生成報告。然後你可以加入AJAX的幻想。

1

如果他們真的由於數據庫命中很多而出現性能問題,那麼我建議您將所有輸入信息填入消息隊列(MSMQ)中。然後你可以在另一端提供一個服務來提取消息並進行數據的批量插入。這樣你有更少的數據庫點擊。然後你可以輸出到更新的文本文件。

1

我會創建一個彙總表,將每小時或每晚捲起來計算總里程數。對於單個請求,您可以從夜間摘要表中加上最後彙總計算和用戶查看頁面以獲取該用戶總數之間的任何其他日誌里程。

你在說多少用戶,每天有多少條記錄?

+0

我不知道現在有多少用戶同時在線,但我知道該網站擁有超過100萬的會員。 如果我從夜總結得到它,那不是實時的嗎?我不知道他們是否希望櫃檯在您查看時積極改變,但我認爲他們希望當瀏覽者加載頁面時儘可能保持最新狀態。 – 2009-07-02 03:03:31

+0

將夜間摘要添加到自從生成摘要以來創建的任何其他日誌記錄將使計算更快。您可以將「當前」日誌保存在一個單獨的表或SQL Server表分區中,而不是那些已經計算爲彙總值的日誌。這將保持在任何給定日期必須動態計算的行數最少。 – jn29098 2009-07-02 03:16:05