2011-11-01 47 views
13

我有兩個類別:Mongoose:populate()/ DBref或數據重複?

  1. 用戶
  2. 上傳


每個上傳都有一個與之關聯的User,我需要知道他們的詳細資料時Upload觀察。是否最好在「上傳」記錄中複製這些數據,或者使用populate()_id引用的用戶集合中提取這些詳細信息?


OPTION 1

var UploadSchema = new Schema({ 
    _id: { type: Schema.ObjectId }, 
    _user: { type: Schema.ObjectId, ref: 'users'}, 
    title: { type: String }, 
}); 


OPTION 2

var UploadSchema = new Schema({ 
    _id: { type: Schema.ObjectId }, 
    user: { 
      name: { type: String }, 
      email: { type: String }, 
      avatar: { type: String }, 
      //...etc 
      }, 
    title: { type: String }, 
}); 


隨着 '選項2',如果任何在Users收集的數據發生變化的我將有通過al更新l關聯Upload記錄。另一方面,使用「選項1」,我可以放鬆心情,讓populate()確保始終顯示最新的用戶數據。

使用populate()的開銷是否顯着?這種常見情況下的最佳做法是什麼?

回答

16

如果您需要在您的用戶查詢,獨自留住用戶。如果您需要查詢上傳內容,請單獨上傳。

你應該問自己的另一個問題是:每當我需要這些數據時,是否需要嵌入對象(反之亦然)?這些數據將被更新多少次?這些數據將被讀取多少次?

想想友誼請求: 每次您需要請求時,您都需要發出請求的用戶,然後將請求嵌入到用戶文檔中。

您也可以在嵌入式對象上創建索引,並且您的搜索將是單聲道查詢/快速/一致。


只是一個類似的問題我之前的回覆鏈接: Mongo DB relations between objects

我覺得這個職位將是適合你http://www.mongodb.org/display/DOCS/Schema+Design

使用案例

客戶/訂單/訂單行 - 商品

訂單應該是一個集合。客戶收集。行項目應該是嵌入在訂單對象中的一系列行項目。

博客系統。

帖子應該是一個集合。帖子作者可能是一個單獨的集合,或者只是一個帖子內的字段,如果只有一個電子郵件地址評論應該是嵌入對象中的表現。

架構設計基礎

凱爾銀行家,10gen的

http://www.10gen.com/presentation/mongosf2011/schemabasics

索引&查詢優化 阿爾文·理查茲,高級迪爾企業埃克特工程

http://www.10gen.com/presentation/mongosf-2011/mongodb-indexing-query-optimization

**這些2個視頻是在mongoddb的最好成績見過恕我直言*

+0

那麼如何更新重複日期呢?在博客示例中,如果我們正在複製用戶信息(例如名稱)的快速單聲道評論記錄的來臨。如果該用戶更改了他們的名字,我們需要在數據庫中更新他們名字的每個實例,在這種情況下,他們每次發表評論。 – wilsonpage

+0

你需要問自己,你會改變你的用戶名多少次?也許一個大規模更新會在你的情況下,或者只是一個ObjectId的用戶文件。對象嵌入是一個選項,而不是一個mongodb道場。 – kilianc

3

Populate()只是一個查詢。所以開銷是無論查詢是什麼,這是你的模型上的find()。 另外,MongoDB的最佳實踐是嵌入你可以。這將導致更快的查詢。這聽起來像你會複製大量的數據,這使得關係(鏈接)成爲一個好地方。

「鏈接」只是將ObjectId放入另一個模型的字段中。

這裏是蒙戈最佳實踐http://www.mongodb.org/display/DOCS/Schema+Design#SchemaDesign-SummaryofBestPractices

鏈接/ DBREFS http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-SimpleDirect%2FManualLinking

+0

我的模式是比這更復雜,我只是簡化了它在這個例子中。用戶可以是多個組的成員,上傳屬於組而不是用戶。你的回答並不回答我的問題:「使用populate()的開銷是否顯着?在這種常見場景中,最佳實踐是什麼?」 – wilsonpage

+0

更新我的答案以更相關。 –