2011-05-03 35 views
1

我有這個架構支持在現場的消息的: enter image description here移動通訊架構的MongoDB

當我將消息發送給其他成員,該消息被保存到信息表;將記錄添加到MessageSent表中,並將每個收件人的記錄添加到MessageInbox表中。 MessageCount用於跟蹤收件箱/發送文件夾中的郵件數量,並使用MessageInbox/MessageSent上的插入/刪除觸發器進行填充 - 通過這種方式,我可以始終知道成員有多少郵件,而不會產生昂貴的「select count( *)「查詢。

此外,當我查詢成員的消息,我加入到會員表獲取成員的名字/姓氏。

現在,我將把應用程序移動到MongoDB,我不太確定應該是什麼集合模式。因爲MongoDB中沒有可用的連接,所以我必須將它完全非規範化,所以我將擁有包含完整消息信息的MessageInbox,MessageDraft和MessageSent集合,對吧?

那我不知道以下幾點:

  1. 如果用戶改變了他的第一/姓氏?它將作爲發件人在一些消息中非正規化存儲,作爲其他消息中收件人的一部分 - 我如何以最佳方式更新它?

  2. 如何獲取消息數量?同時會有大量的請求,所以它必須表現良好。

任何想法,意見和建議,非常感謝!

回答

1

我可以爲您提供一些見解,以瞭解我在MongoDB中如何模擬JOIN。

在這種情況下,我將相應用戶(或多個用戶)的ID存儲在給定對象中,例如消息集合中的消息對象。

(我不是暗示這是您的架構,只是用它作爲我的做法的一個例子)

{ 
    _id: "msg1234", 
    from: "user1234", 
    to: "user5678", 
    subject: "This is the subject", 
    body: "This is the body" 
} 

我就查詢數據庫得到那麼我需要在我的應用程序會遍歷所有的消息結果並構建一組用戶標識。我會過濾這個數組是唯一的,然後使用$in運算符第二次查詢數據庫,以找到給定數組中的任何用戶。

然後在我的應用程序中,我會將結果加回到對象。

它需要對數據庫進行兩次查詢(或者如果您想加入其他集合,則可能需要更多查詢),但這說明了許多人長期以來一直倡導的內容:在應用程序層中執行JOIN操作。讓數據庫花時間查詢數據,而不是處理它。無論如何,你可能比你的數據庫更快,更便宜地擴展你的應用服務器。

我正在使用此模式在我的應用程序中創建實時活動源,並且它的工作完美且快速。我更喜歡這樣去規範可能會像用戶信息那樣變化的東西,因爲當寫入數據庫時​​,如果新數據不適合舊數據的位置,MongoDB可能需要重寫整個對象。如果我需要在數據庫中重寫數百(或數千)個活動項目,那麼這將是一場災難。

另外,在MongoDB上的寫入被阻塞,所以如果像我剛剛描述的情況發生,所有的讀寫操作都會被阻塞,直到寫操作完成。我相信這個計劃將在2.x系列的某些能力中得到解決,但它仍然不會很完美。

另一方面,索引查詢速度非常快,即使您需要執行其中的兩個來獲取數據。

+0

這是個好主意。收集信息的任何想法都是以表演的方式計算的? – Andrey 2011-05-03 00:51:52

+1

這樣做的最好方法可能是將計數預先存儲在某處。 MongoDB 2.x計劃有額外的聚合操作符,比如$ sum,但還沒有。對於這樣的事情,您可能只想將它存儲在某個地方,並在發送消息時使用$ inc操作符來增加它。 – 2011-05-03 01:33:07