个性化阅读
专注于IT技术分析

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)})
赞(0)
未经允许不得转载:srcmini » mongodb进阶开发教程:数据库关系和引用原理和使用详解

评论 抢沙发

评论前必须登录!