2010-10-20 36 views
4

背景:Recomendations爲PHP和MySQL統計報告的Web應用程序

我在小公司「繼承」一個PHP Web應用程序和 經過多年的嘮叨終於得到了 去扔掉麪條代碼並重新開始。

我們要日誌在系統由例如每一個動作:

  • 用戶X的角度觀測項目Y
  • 用戶X更新項目Y
  • 在Z城
  • 新項目Y

及更高版本提供了有關在系統中完成的操作的不同分辨率(日,月,年) 的圖形。

在以前的版本中,我們有一個自2000年以來有2000,000條記錄的表,因此這會讓您知道我們已有的數據庫數量,這只是針對許多統計數據之一。

實際問題:

什麼建設一個接近實時 系統來創建此統計你有recomendations?

筆記:

  1. 圖形是通過谷歌的可視化API已經覆蓋
  2. 我不是adversed使用任何NoSQL數據庫或 郵件服務器,crons或不管這得到 完成任務,但會比較喜歡mysql/php 解決方案
  3. 我目前的思路是 自動爲每個 創建一個表我想保存,並創建 幾個聚合表(按月,按天,按年) 來緩存結果。
  4. 我知道是一個很寬泛的問題,但任何建議,歡迎

回答

2

如果所有用戶都必須進行登記我想了一個完整的解決方案標準化去。

USERS TABLE   OBJECTS TABLE 
---------------  -----------------  
user_id (primary)  object_id (primary) 


USERS_TO_OBJECTS TABLE 
-------------------- 
user_id (index) 
object_id (index) 
time (index) 
action (index) 
? object_type (index) // could be useful to speed things up 

這種設置可能會給你最好的靈活性,同時圖表,也將是非常快的,你可以離開了用戶或對象,如果你不需要他們。

編輯:

說X市(編號9876)被更新的用戶123(編號1234)...

1234 - user_id (the user that did the action) 
9876 - object_id (the object where the action was done) 
xyz  - time 
updated - action type (so that you select only specific actions) 
city - object type (so that you select only specific objects) 

我已經養活了這個表40M行和結果是相當可接受的。

0.002秒有關在上週更新的城市數量的簡單計數。數據是隨機插入的。

編輯2

如果你發現自己有一個非常巨大的表,你可以訴諸MySQL的分區和您的模式是完美的。我真的不知道該怎麼你會使用表,但你可以:

PARTITION BY範圍。在日期上組織分區。每隔一個月左右你就會有一個新的分區。

PARTITION BY KEY。通過操作組織分區。每一個行動都是爲了適當的分割。

您可以檢查出more on partitions on MySQL's sitethis article gives you some detail成細tunning分區。

+0

感謝@Frankie,我期待很多行,存儲在同一個表的所有統計數據將使巨大而緩慢的。再加上一些統計數據有額外的信息,例如在城市Z上的新項目Y其並非總是user_id。 – 2010-10-20 02:12:16

+0

@Mon Villalon,我已經做了一些測試並相應地更新了答案。如果所有的查詢都採用好的索引,40M行應該沒有問題。不過,如果你發現數據庫正在掙扎,你可能會訴諸分區。 – Frankie 2010-10-20 02:28:15

1

你可以考慮像Redis這樣的「數據庫」。 Redis的採用鏈表存儲列表類型,所以你可以很容易地只是LPUSH到一個列表,像這樣:

$action = array(
    "type"=>"page_view", 
    "url"=>"/example/path", 
    "user"=>"user1", 
    "timestamp"=>$_SERVER["REQUEST_TIME"] 
); 
$r = new Redis(); 
// Redis connection info // 
$r->lPush("global_history", json_encode($action)); 

的LPUSH工作在O(1)運行,因而,不應該是一個問題。檢索結果可能會有點棘手(列表的時間爲O(n))。 Redis也基本上是基於內存的(儘管開發版本包括「虛擬內存」支持),所以速度很快,但是您可能會很容易地將空間用完。

我使用這種技術來記錄歷史和統計的音樂網站我運行。它非常成功,只需很少的努力就能提供非常快速的結果。

如果您希望使其更穩定,可以使用Hadoop或其他技術從列表末尾(RPOP)拉出並將結果歸檔爲更永久的格式(例如,將XML推送到Amazon S3) 。然後,您可以讓Google Visualizations在查看舊數據時從歸檔中查找他們的數據(這將是靜態編譯數據),Redis前端查看更新的數據。

希望這會有所幫助!

0

我很高興你終於拿到了綠燈重新設計該項目。可能在這裏回覆太晚了,但MongoDB的實現(帶有Capped Collections功能)可以更好地完成這種工作。實施它不是太耗時,所以也許還有機會。

無論如何,希望一切順利。