2009-03-04 168 views
10

我必須按照用戶活動的日,周,月和年收集統計信息。我是DB設計階段,我想正確地完成這個階段,因爲它會讓我的編碼生活更輕鬆。用於按日,周,月,年保存統計信息的數據庫結構

我所要做的只是簡單地在每次活動發生時在數據庫中將字段中的值增加1。那麼我可以每天,每週,每月和每年提出日期。我的數據庫應該如何構建?如果對大多數人來說這是一個簡單的問題,請道歉如果這種結構可以擴展以便可以按照其他類別進行細分,那也是很好的。

有問題的是每個月都是由多個日子組成的,這些日子是每個日曆年都會改變的。

謝謝大家的幫助或指導。

其他信息:Linux的機器,利用PHP和MySQL

回答

19

,而不是更新,一週每天計數等只是行插入表中每一個活動發生這樣的時刻:

insert into activities (activity_date, activity_info) 
values (CURRENT_TIMESTAMP, 'whatever'); 

現在,您的報告中都像很簡單:

select count(*) from activities 
where activity_date between '2008-01-01' and '2008-01-07'; 

select YEARWEEK(`activity_date`) as theweek, count(*) 
group by theweek 
+1

如果例如記錄的活動每次都發生時,這個表是否會變得非常大頁面被加載了一個網站,並且有很多用戶在這個網站上持有賬戶? – Abs 2009-03-04 14:21:39

+1

是的。這是你應該從最初的設計開始。優化可能會晚些時候。 – thomasrutter 2009-03-04 14:29:33

4

您可以使用集合函數將記錄添加到表格中並將其添加到SELECT中。

如果由於某種原因,你需要保留彙總統計,你可以使用:

CREATE TABLE aggregates (type VARCHAR(20), part VARCHAR(10) NOT NULL PRIMARY KEY, activity INT) 

INSERT INTO aggregates (type, part, activity) 
VALUES ('year', SUBSTRING(SYSDATE(), 1, 4), 1) 
ON DUPLICATE KEY UPDATE activity = activity + 1 

INSERT INTO aggregates (type, part, activity) 
VALUES ('month', SUBSTRING(SYSDATE(), 1, 7), 1) 
ON DUPLICATE KEY UPDATE activity = activity + 1 

INSERT INTO aggregates (type, part, activity) 
VALUES ('day', SUBSTRING(SYSDATE(), 1, 10), 1) 
ON DUPLICATE KEY UPDATE activity = activity + 1 

這將自動更新現有行並插入不存在的必要時。

3
  1. 事件表:id,activity id,datetime,userid。
  2. 表的用戶:ID,用戶名等活動
  3. 表:ID,活動名稱等

只需輸入一行新的事件時事件發生。然後你可以分析事件,但操縱時間,日期,用戶,活動等。

2

首先,你可能會想象一個單一的表,因爲這將是最規範化的形式。該表格只會包含您收到的每個命中的條目,每行包含該命中的日期/時間。

現在,通過這種方式,爲了獲得每小時,每天,每週等的統計數據,查詢很簡單,但是您的數據庫必須執行一些相當繁重的查詢工作。特別是,執行求和,計數或平均值的查詢將需要獲取所有相關的行。

您可以通過在第二個表中預先計算所需的計數並確保將該表定期與第一個表同步來解決此問題。問題是,您將負責讓自己的緩存保持同步。

這可能會涉及每個小時做一行。如果您每天只能獲取最多24行,那麼查詢一天或一個月的速度仍然會更快。

您的其他建議是從一開始就將它聚合起來,絕不會將每一個命中行存儲爲一行。像以前一樣,你可能會這樣做,每小時一排。每一擊都會使有關小時數增加1。你只能將數據放在一個位置,而且它已經很好地總結了。

我建議小時而不是白天的原因是,這仍然可以讓您選擇支持多個時區。如果您的粒度僅限於當天,那麼您沒有該選項。

1

託尼·安德魯斯的答案是最簡單的,但是雪花結構有時用於數據倉庫應用程序:一個表包含所有活動,另一個表示每天的活動,另一個表示每月的活動,第三個表示活動年。利用這種結構,可以非常有效地計算任意兩個日期之間的活動。 https://en.wikipedia.org/wiki/Snowflake_schema

1

使用星型模式設計。 (或者可能是雪花設計)。

Star-Schema Design

你最終會做插入到事實表中的每個新的活動。見託尼的建議。

您至少需要兩個維度表,一個用於用戶,另一個用於時間範圍。可能會有活動類型的維度,甚至可能是位置。這取決於你想要對數據做什麼。

您的問題涉及時間範圍的維度表。我們稱之爲「年曆」。選擇一個粒度。讓我們說一天。年曆每天會有一行。主鍵可以是日期。您的事實表應該包含此主鍵作爲外鍵,以便更輕鬆地進行聯接。 (無論您是否將其聲明爲外鍵,隻影響更新過程中的參照完整性。)

在您可以想到的每個報告週期的年鑑中包含列。周,月,季,年等。甚至可以包括與公司自己的日曆相關的報告期。

這是一篇比較ER和DM的文章。我很不尋常,因爲我喜歡這兩種方法,爲適當的任務選擇合適的方法。

http://www.dbmsmag.com/9510d05.html

0

你的問題涉及到時間幀維度表。我們稱之爲「年曆」。選擇一個粒度。讓我們說一天。年曆每天會有一行。主鍵可以是日期。您的事實表應該包含此主鍵作爲外鍵,以便更輕鬆地進行聯接。 (無論你是否聲明它是一個外鍵,只會影響更新過程中的參照完整性。)

相關問題