2013-09-23 21 views
1
其他文件

比方說,我有兩個類別:引用的字符串,而沒有的ObjectId

ProductsCategories

後者收集的文件有2個字段:

  • _id(BSON ObjectId
  • 名稱(字符串)

後者收集的文件有3個領域:

  • _id (BSON ObjectId
  • 名稱(字符串)
  • 產品(字符串數組)

假設我有以下Product文件:

{ "_id" : ObjectId("AAA"), "name" : "Shovel" }

比方說,我有以下Category文件:

{ "_id" : ObjectId("BBB"), "Name" : "Gardening", "Products" : ["AAA"] }

爲了本示例的目的,假設AAABBB是合法ObjectId的 - 例如:ObjectId("523c7df5c30cc960b235ddee")它們將等於內部ObjectId的字符串。

Products字段應該存儲爲ObjectId(...)而不是字符串嗎?

回答

1

我不認爲這真的很重要。

我很確定ObjectId格式是對十六進制數進行編碼,所以它對內存和帶寬的效率可能稍高一些。我已經完成了這兩種方式。只要你決定,爲每個領域,你將如何編碼它,要麼會工作得很好。

0

當您嘗試從Categories集合中查找產品的詳細信息時,這將最重要。

由於Mongo中沒有服務器端JOIN,您的代碼必須將文檔匹配在一起。 ObjectIDs are encoded as 12 bytes,你可以輕鬆地用任何語言進行比較。使用字符串或對象標識符並不重要。

您正面臨的真正問題是數據規範化(或缺乏)之一。如果您將Name字段存儲在Categories文檔中,而不是ObjectID,那麼您將能夠在一次調用中返回產品名稱(而不是多次調用,每個產品類別爲1次)。

第一次做這件事感覺不對。畢竟,如果您更改產品的名稱(可能會也可能不常見),您將不得不更新許多文檔。您必須考慮應用程序使用它的方式來建模數據。

最後,指數Name屬性Prodcuts收藏。從您在Categories文檔中找到的字符串開始獲取產品的詳細信息將很快。

另一種方法是根本沒有分類集合,但要在您的Products文檔中添加Category屬性。您可以找到具有{'Category':'Gardening'}的文檔。索引Category字段可能是一個好主意。

此外,對象ID或字符串並沒有多大關係。這是關於爲你的數據建模思考你的應用程序將如何使用它。

+0

迴應:'如果你存儲的名稱字段......在一個叫」 - 我可以達到同樣的,如果我正確,如果使用'的ObjectId(...)',而不是字符串,右 –

+0

不?你想在一個類別中顯示產品的名稱,我想你的應用程序會顯示類別,並列出可供選擇的產品名稱,你已經有了這些名稱,我將用另一種方式更新答案,以便查看它。 – ixe013

1

只要一致使用相同類型的(使得比較正確地發生),所不同的是:

  1. 一個ObjectId不能與相同ObjectId值的String表示。因此,ObjectId("523c7df5c30cc960b235ddee")不等於"523c7df5c30cc960b235ddee"
  2. ObjectId S,本機存儲時,將被存儲爲12個字節,加上字段名稱
  3. 一種ObjectId,當作爲字符串存儲的,將通常被存儲在24個字節(因爲它會被轉換爲十六進制數)加字段名
  4. 比較可以更稍微更有效地進行與12字節數,因爲它比較更少的字節。它不會在大多數類型的使用雖然重要,所以這是一個微型優化(但你應該知道)
  5. 獎金 - 如果你不使用短縮寫字段名稱,使用ObjectId本身的規模效益因爲12字節確實無關緊要,因爲當以字符串形式存儲字段名稱時,字節的大小將遠遠超過字節的大小。

我建議將它們存儲爲原生ObjectId s。某些驅動程序可以選擇性地將其轉換爲ObjectId,然後再轉換爲String,以便客戶端代碼可以更輕鬆地對其進行操作。例如C#驅動程序可以做到這一點,我已經使用它,所以當序列化爲JSON時,ObjectId採用簡單的格式,很容易在JavaScript中使用。