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 看起来你只需要插入更多数据而没有任何优势......如果我错了,请纠正我。

4

2 回答 2

5

基本上,DBRef 是一个自我描述的 ObjectID,它是一个存在于所有驱动程序(我认为所有驱动程序)中的客户端助手,它提供了在您的应用程序中轻松获取相关行的能力。

他们不是:

  • 加入
  • 可级联关系
  • 服务器端关系
  • 已解决的服务器端

它们也没有在 Map Reduce 中使用,由于分片的复杂性,该功能被取消。

但是,使用这些并不总是很好,因为如果您知道与该行相关的集合与仅存储 ObjectID 相比,它们会占用相当多的空间。不仅如此,而且由于它们的解析方式,如果能够(轻松)形成一个范围以一次性查询相关行,则每个相关记录都需要一个一个延迟加载,因此它们可以增加查询量您也对数据库进行了操作,从而增加了游标。

于 2013-02-12T08:11:39.307 回答
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 数组可能包含水果集合中的引用,但也包含蔬菜集合。在这种情况下,DBRef 实际上会很方便。

于 2013-02-12T06:13:59.300 回答