2012-03-03 94 views
2

我有一個Parent的集合,其中包含EmbeddedThing s,並且每個EmbeddedThing都包含對創建它的User的引用。mongodb:這是我應該正常化嵌入對象嗎?

UserCollection: [ 
    { 
    _id: ObjectId(…), 
    name: '…' 
    }, 
    … 
] 

ParentCollection: [ 
    { 
    _id: ObjectId(…), 
     EmbeddedThings: [ 
     { 
     _id: 1, 
     userId: ObjectId(…) 
     }, 
     { 
     _id: 2, 
     userId: ObjectId(…) 
     } 
    ] 
    }, 
    … 
] 

我很快就意識到,我需要得到所有EmbeddedThing■對於給定的用戶,這是我管理使用的map/reduce來完成:

"results": [ 
    { 
    "_id": 1, 
    "value": [ `EmbeddedThing`, `EmbeddedThing`, … ] 
    }, 
    { 
    "_id": 2, 
    "value": [ `EmbeddedThing`, `EmbeddedThing`, … ] 
    }, 
    … 
] 

這是我應該真的只是正常化EmbeddedThing成它自己的集合,還是應該保持map/reduce來完成這個工作?也許有其他設計?

如果有幫助,這是爲了讓用戶在所有Parent s上看到他們的EmbeddedThing s列表,而不是一些報告/聚合任務(這讓我意識到我可能會做這個錯誤)。

謝謝!

回答

2

「嵌入或不嵌入:這是一個問題」 :)

我的規則是:

  • 嵌入如果嵌入對象僅在父對象的情況下具有意義。例如,OrderItem沒有Order沒有意義。
  • 如果由性能要求決定,則嵌入。閱讀完整的文檔樹非常便宜(而不是必須進行多個查詢並以編程方式加入)。

你應該看看你的訪問模式。如果每秒載入ParentThing幾千次,並且每週載入User一次,那麼map-reduce可能是一個不錯的選擇。用戶查詢速度會很慢,但對您的應用程序來說可能沒問題。

另一種方法是進一步去規範化。也就是說,當你添加一個嵌入的東西時,將它添加到父項和用戶。

  • 優點:查詢速度很快。
  • 缺點:複雜的代碼。雙倍的寫入。潛在的同步丟失(您在一個地方更新/刪除,但忘記在另一個地方)。
+0

我喜歡mongodb的靈活性,但真的很討厭「依賴」部分,因爲我必須考慮額外的東西:)因爲這是一個全新的項目,我只能猜測訪問模式。也因爲它是新的,我專注於開發的便捷性,而不是速度。聽起來就像我現在應該遠離反正常化那樣! – thatmarvin 2012-03-03 07:49:52

+0

@thatmarvin:思考對你有好處:) – 2012-03-03 07:50:43