Performance

MongoDb Join VS 嵌套查詢

  • July 21, 2019

我正在嘗試建構一個遊戲伺服器,我們使用 MongoDb 作為數據庫。

我們有一個包含Games這樣模型的集合:

{
   "_id" : ObjectId("5d1b345b8ea742034db76431"),
   "Users" : [
       {
           "_id" : "0e76bd95-a7c2-4e15-b2bc-4cdf741fe9aa",
           "UserName" : "l98lNhLHPh",
           "Cards" : [
               249
           ]
       },
       {
           "_id" : "6ffec61d-45cc-46fa-a1f0-2a3e0a03fef6",
           "UserName" : "Vun12sWp4W",
           "Cards" : [
               234
           ]
       }
   ],
   "CreatedAt" : ISODate("2019-07-02T15:09:23.303+04:30"),
   "UpdatedAt" : ISODate("2019-07-02T15:09:23.674+04:30"),
   "IsFinished" : false
}

我們可以很方便地查詢參與過遊戲的使用者,但是如果我們需要知道某個特殊使用者之前玩過的遊戲怎麼辦?

我們達成了兩種解決方案,但我們不知道哪一種更好。

首先,使用帶有索引的嵌套欄位進行查詢Users.UserNamedb.games.find({"Users.UserName":"Amin"})

其次,創建一個包含UserGames數據的新集合。

// collection: UserGames
{
   "_id" : ObjectId("5d1b35c58ea742034db79fea"),
   "UserId" : "6ffec61d-45cc-46fa-a1f0-2a3e0a03fef6",
   "GameId" : ObjectId("5d1b35c58ea742034db79fe9")
}

並加入GamesUserGames收藏以查找哪個使用者玩了哪些遊戲。

我來自關係數據庫思維模式,我不知道應該採用哪種方法?

規範的答案是使用兩種模式創建範例數據,並分析您將要執行的查詢以查看哪個模式執行得更快:-)

但我猜你實際上會看到相同的性能。只要您索引子欄位(您在第一個選項中所做的),Mongo 查詢子文件的速度就非常快。

因此,在這兩種方法之間做出決定的真正方法是真正了解您的數據和您的查詢/訪問模式。例如,創建連接表的一個優點是您可以將所有附加數據(如“使用者名”和“卡片”)移動到連接表中。這會縮小你的遊戲記錄。如果您將有大量遊戲伺服器實時創建大量遊戲數據,並且不同的使用者託管在不同的伺服器上,這可能會很有用,這意味著在遊戲發生時更新使用者數據可能會導致鎖定和爭用問題。的使用者數據儲存在一個大遊戲記錄中。在這種情況下,連接表更有意義,因為每個使用者-遊戲組合都是一個單獨的記錄,可以單獨更新(如果您的遊戲變得非常流行,甚至可以分片到單獨的伺服器上:

另一方面,如果您預計不需要實時對使用者遊戲數據進行大量寫入和更新,那麼將所有這些數據保存為子文件可以使查詢更易於編寫。

歸根結底,這確實取決於您的訪問模式。原始讀取性能可能是等效的,但這只是確定在您的方案中最佳的因素之一。

引用自:https://dba.stackexchange.com/questions/241873