2011-09-19 15 views
2

我有一個由PHP編寫的基於Web的即時通訊應用程序。最近我從mysql遷移到了couchdb,我認爲這通常是一個好主意,目前它的工作狀況非常好。我不需要視圖等。基本上我通過ID獲取文檔。couchdb -json在Messenger應用程序中的性能

但是我對性能有些懷疑。兩個用戶之間的對話存儲在單個文檔中。例如在A和B之間,我有一個文檔,在C和B之間我有另一個文檔等。

我從不刪除日誌,並且當這兩個用戶之間啓動新對話時,我使用json_decode解碼存儲的文檔,打印出最近的兩個用戶的會話記錄。當他們中的一個寫新內容時,我在數組的末尾添加新的聊天行(我從文檔中獲得),將數組重新編碼爲json,最後更新文檔。

對不對?在no-sql數據庫中存儲這種大型數組的最佳做法是什麼?

回答

7

我會對它進行不同的建模;爲每件事說一份文件。 {「from」:「foo」,「to」:「bar」,「text」:「hey there」}。因此,您只能製作新文檔,而且每份文檔都保持非常小。

添加一個時間戳,然後使用該時間戳上的視圖來重建對話。

您將需要使用服務器的時間來確保正確的順序,所以我建議您通過更新處理程序(http://wiki.apache.org/couchdb/Document_Update_Handlers)進行更新並在其中添加時間戳。

1

解決方法是偶爾將舊郵件捆綁到CouchDB attachments。當通過文檔ID查詢時,這些將不可見。

例如,會話文件:

{ "_id": "alice_bob" 
, "_rev": "123-abcdef" 
, "messages": 
    [ "alice: Hi, Bob!" 
    , "alice: Are you there?" 
    , "bob: Yes, what's up?" 
    , // ... etc. 
    , "bob: Thanks!" 
    ] 
} 

例如,如果對話長度大於200點的消息,然後將它分割成兩個陣列:

  • 最舊的消息的150( "alice: Hi, Bob", and the next 149)
  • 50最新留言:(49條留言,最高可達"bob: Thanks!"

將附件中的舊郵件存檔,可能帶有時間戳。

{ "_id": "alice_bob" 
, "_rev": "123-abcdef" 
, "_attachments": 
    { "2011-09-19T17:29:17.293Z.json": 
    { "content_type": "application/json" 
    , "data": /* 150 message JSON string goes here */ 
    } 
    } 
, "messages": [ /* latest 50 messages go here */ ] 
} 

當你獲取/db/alice_bob你會得到附件數據;但是,您可以直接從此URL獲取甚至刪除附件。

/db/alice_bob/2011-09-19T17:29:17.293Z.json 

請注意,這主要是一種變通方法。好處是你不必改變你的PHP代碼。 (歸檔消息可以是後臺進程。)但從長遠來看,Robert的技術更具可擴展性和正確性。