2013-02-12 100 views
7

我想爲我的應用程序使用mongo,當我考慮設計問題時,我想出了問題,那麼DBRef的優點/目的是什麼?

例如:

> names = ['apple', 'banana', 'orange', 'peach', 'pineapple'] 
[ "apple", "banana", "orange", "peach", "pineapple" ] 
> for (i=0; i<5; i++) { 
... db.fruits.insert({_id:i, name:names[i]}) 
... } 
> db.fruits.find() 
{ "_id" : 0, "name" : "apple" } 
{ "_id" : 1, "name" : "banana" } 
{ "_id" : 2, "name" : "orange" } 
{ "_id" : 3, "name" : "peach" } 
{ "_id" : 4, "name" : "pineapple" } 

,我想存儲在一個籃子收集那些水果:

> db.basket.insert({_id:1, items:[ {$ref:'fruits', $id:1}, {$ref:'fruits', $id:3} ] }) 
> db.basket.insert({_id:2, items:[{fruit_id: 1}, {fruit_id: 3}]}) 
> db.basket.find() 
{ "_id" : 1, "items" : [ DBRef("fruits", 1), DBRef("fruits", 3) ] } 
{ "_id" : 2, "items" : [ { "fruit_id" : 1 }, { "fruit_id" : 3 } ] } 

什麼是這兩個技術之間的真正區別?對我來說,它看起來像使用DBRef你只需插入更多的數據沒有任何優勢....請糾正我,如果我錯了。

回答

5

基本上,DBRef是一個自我描述ObjectID,它存在於所有驅動程序(我認爲全部)中的客戶端輔助程序提供了在您的應用程序中輕鬆獲取相關行的功能。

他們不是:

  • JOIN的
  • 可級聯關係
  • 服務器端的關係
  • 解析的服務器端

他們還沒有在地圖中使用減少的由於分片的複雜性,功能被取消了。

雖然使用這些並不總是很好,但如果您知道與該行相關的集合與存儲ObjectID相比,那麼它們會花費相當多的空間。不僅如此,而且由於它們是如何解決的,每個相關記錄都需要逐個加載,如果能夠形成一個範圍(很容易)一次去查詢相關的行,那麼它們可以增加查詢量你也對數據庫做出反應,反過來增加遊標。

4

從「MongoDB的權威指南」是DBREFS沒有必要和存儲MongoID更輕盈,但提供DBREFS像下面的一些有趣的功能:

文檔中的每個加載DBREF:

var note = db.notes.findOne({"_id":20}); 
note.references.forEach(function(ref) { 
    printjson(db[ref.$ref].findOne({"_id": ref.$id})); 
}); 

如果引用存儲在不同的集合和數據庫中,它們也很有用,因爲DBRef包含該信息。如果您使用MongoID,則必須記住MongoID所引用的數據庫和集合。

在您的示例中,籃子文檔的items數組可能包含fruits集合中的引用,但也會收集蔬菜。在這種情況下,DBRef實際上會很方便。