2013-01-07 82 views
1

我需要使用Spring Data爲MongoDB中的用戶存儲朋友關係。我的「模式」解決方案是在用戶文檔中存儲朋友的用戶名(也是_id)。我沒有使用DBRef,因爲Spring Data和DBRef在自我關係上似乎存在問題(朋友是用戶:p)。一個簡單的用戶文件是這樣的:mongoDB朋友關係和原子更新

{ 
"_id" : "user1", 
"email" : "[email protected]", 
"friendRequests" : { 
    "user4" : 0 
}, 
"friends" : ["user2", "user3" ], 
"password" : "$2a$10$9iJWLZjBSu3rq19wh7KTduNXIVcXozsNVjwVogO9eoz0uXO52Z2NC" 
} 

我覺得這個模型已經足夠好了。但是,當有人接受好友請求時,我必須更新這兩個用戶的文檔,而且操作不是原子性的。可能會出現一些情況,其中只有一個被更新。這不是關鍵數據,但仍然會很高興爲此提供解決方案。我是否在說這個?我在兩階段提交http://cookbook.mongodb.org/patterns/perform-two-phase-commits/上發現了這個文檔,但是對於這種情況來說似乎太多了,儘管它很容易實現。

回答

1

如果不知道應用程序如何使用數據,很難回答這些類型的問題。請記住,在MongoDB中,有很多不同的方式來表示基本相同的數據/模式,所以最適合您的應用程序的方式是適合您應用程序需求的方式。

有些問題要問自己:
你知道每個用戶平均有多少朋友?
你將如何顯示/查詢/更新用戶的朋友?
以上哪些操作需要高性能且絕對最新,哪些操作可能需要更長時間,或者稍後在批處理模式下完成?

對於每種可能的數據模式都有權衡。將用戶名不斷添加到每個用戶的朋友數組中意味着文檔將不斷增長(這對於執行更新是次優的,因爲當文檔超出了分配的空間時,下次更新時需要移動它)。爲了彌補這一點,你必須考慮你以這種方式存儲一系列朋友時所獲得的收益。它是否使您在獲取有關用戶的所有信息時僅進行一次讀取?或者你還需要再次閱讀(也許再次查詢用戶集合以獲取關於每個用戶在朋友陣列中的其他信息?

您已經在考慮更新的原子性,這有助於保持數據的一致性,但作爲你正確地注意到,這是你的應用程序可以處理的東西(或者你可以有一個後臺作業運行並檢測到任何「中途」友誼更新並清理它們)。爲集合建立索引 - 如果您需要單個集合上的許多索引來滿足查詢的SLA,那麼您的更新/插入必然會變得更慢(因爲還需要更新更多的索引),這可能沒問題,但只有您可以做出有關的決定權衡。

我希望這會有所幫助。

+0

感謝您的回答!很難說現在有多少用戶可以擁有。這不是應用程序的核心功能,至少在我的腦海中此刻。我使用這個解決方案,因爲在這裏的其他答案建議在stackoverflow。目前我唯一想到的另一個解決方案是使用另一個集合來存儲友誼 – alex