mongodb进阶开发教程(数据库关系和引用原理和使用详解)

【mongodb进阶开发教程(数据库关系和引用原理和使用详解)】前面两篇中我们讨论了mongodb在java和php中的实战开发:JavaWeb和mongodb增删改查,php mongodb数据库开发。这篇文章开始讨论mongodb中的数据库关系和引用的原理和使用,关系也就是1对多或多对1这样的关系,关系可以通过嵌入和引用的方法建模,这种关系可以是:1:1一对一、1:N一对多、N:1多对一的关系或N:N多对多的关系。
让我们考虑为用户存储地址的情况,一个用户可以有多个地址,这是一个1:n的关系,如下是用户user的文档结构:

{ "_id":ObjectId("uu"), "name": "Ao", "contact": "369", }

如下是用户的地址address的文档结构:
{ "_id":ObjectId("aa"), "building": "22 A, Fool Apt", "city": "LosC", "state": "China" }

1、建立嵌入式关系在嵌入式方法中,我们将地址文档嵌入到用户文档中。
{ "_id":ObjectId("ee"), "name": "EW", "contact": "123", "address": [ { "_id":ObjectId("bb"), "building": "30B", "city": "Pin", "state": "China" }, { "_id":ObjectId("cc"), "building": "2 St", "city": "xIN", "state": "China" } ] }

这种方法在单个文档中维护所有相关数据,这使得检索和维护变得很容易。可以在单个查询中检索整个文档,比如:
db.users.findOne({"name": "EE"},{"address": 1})

使用嵌入式的缺点是,如果嵌入式文档的大小持续增长,就会影响读写性能。
2、使用手动引用构建关系这就是设计归一化关系的方法,用户文档和地址文档将分别维护,用户文档将包含一个引用地址文档id字段的字段,如下:
{ "_id":ObjectId("ee"), "name": "EW", "contact": "123", "address_ids": [ "_id":ObjectId("bb"), "_id":ObjectId("cc"), } ] }

在上面的用户文档中包含数组字段address_ids,其中包含相应地址的对象。我们需要两个查询:首先从用户文档获取address_ids字段,然后从地址集合获取这些地址信息。
>var result = db.users.findOne({"name": "EE"}, {"address_ids": 1}) >var addresses = db.address.find({"_id": {"$in": result["address_ids"]}})

3、mongodb数据库引用上面关于MongoDB关系的建模使用了引用关系的概念,也称为手动引用,在其中我们手动地将引用文档的id存储在其他文档中。但是,在文档包含来自不同集合的引用的情况下,我们可以使用MongoDB数据库引用。
(1)数据库引用手动引用的对比
作为一个示例场景,我们将使用数据库引用而不是手动引用,考虑这样一个数据库:我们将不同类型的地址(家里的、办公地点、邮件地址等)存储在不同的集合中。文档引用地址时它还需要根据地址类型指定查看哪个集合。在文档引用来自许多集合的文档的情况下,我们应该使用数据库引用。
(2)使用数据库引用
数据库应用有三个属性:
a、$ref –表示引用目标文档的所在集合名称
b、$id——对应所引用文档的_id
c、$db——这是一个可选字段,包含引用文档所在的数据库的名称
考虑一个具有数据库引用字段地址的示例用户文档,如代码片段所示
"_id":ObjectId("cc"), "contact": "369", "name": "PE", "address": { "$ref": "address_home", "$id": ObjectId("gg"), "$db": "website" }

这里的address 数据库引用字段指定引用的地址文档位于website数据库下的address_home集合中,其id为gg。
下面的代码动态地在$ref参数指定的集合(在本例中为address_home)中查找一个id由数据库应用中的$id参数指定的文档。
>var user = db.users.findOne({"name": "CC"}) >var dbRef = user.address >db[dbRef.$ref].findOne({"_id": (dbRef.$id)})

    推荐阅读