虽说MongoDB是非关系型数据库,但由于大部分情况下数据之间是存在关系的,所以MongoDB也需要一些方式来表达数据之间的关系。MongoDB表达数据关系的方式有两种:文档嵌套和数据库引用。

一、文档嵌套

众所周知,MongoDB可以在一个文档中嵌套多个子文档,这在解决一对一和一对多的数据关系中是很有用的,在Mysql等关系型数据库中需要建立和查询两个表才能完成的事情在MongoDB中只需要一个集合就能搞定了。在MongoDB中表达一对一和一对多数据关系的时候,应该优先考虑使用文档嵌套的方式,而不是数据库引用。前者无论存储还是查询与维护都比较简单,只需要对一个集合进行操作,而且比数据库引用高效,因为存在关联关系的数据在磁盘中存储的位置相近。

  然而,使用文档嵌套的方式无法解决多对多的数据关系,而且也并不是所有的一对一和一对多数据关系都是可以使用文档嵌套方式来解决的。目前MongoDB对单个文档的大小限制是16M,所以如果需要嵌套的子文档数据量太大的话就无法使用文档嵌套的方式了,就算MongoDB没有这个限制,单个文档数据量太大也是会影响读写性能的,这时候就应该使用数据库引用了。

二、数据库引用

  MongoDB的数据库引用有两种实现方式:手动引用、使用DBRef标准。由于MongoDB不支持表连接查询,所以这两种引用方式查询的时候都需要进行两次查询。

1. 手动引用

  这种方式比较简单,有点类似Mysql的外键功能。比如现在有两个集合:users和article,在users中可以使用用户的名字作为_id键值,然后在article中某个字段存储文章的作者名字。这样查询某个文章信息的时候,先查询查出article中的文档,然后再根据其中的作者名字,前往users查询作者的信息,需要两次查询。示例如下:

 2. DBRef标准

  DBRef就像URL,唯一确定一个到文档的引用,它自动加载文档的方式正如网站中URL通过链接自动加载web页面一样。DBRef完整的定义格式如下:

{‘$ref’:collection,’$id’:id_value,’$db’:database}

这三个键的顺序是不能改变的。其中‘$ref’指定引用文档所在集合,’$id’指定引用文档_id键的值,’$db’指定引用文档所在数据库,第三个参数是可选的,跨数据库引用时才需要使用该键。DBRef使用示例如下:

可以看出,其实质就是在文档中存放一个内嵌子文档,记录引用文档所在的集合名称和_id键的值,查询的时候先查询这个文档本身,再利用内嵌文档到指定的引用集合查询指定的文档。

  看起来使用DBRef标准引用文档和手动引用的原理其实是一样的,没什么差别,甚至手动引用使用起来还要简单些,那为什么还需要DBRef呢?使用手动引用的方式,当前文档只是记录了引用文档的_id键值,并没有记录引用文档所在集合,所以开发者需要自行记得其引用的文档是在哪个集合里面的;而DBRef引用中则记录了引用文档所在数据库、集合,还有引用文档的_id键值,可以引用任何一个数据库任何一个集合的文档,而开发者无需记得引用的文档是在哪里的,而且,DBRef在需要引用多个文档的时候比较方便,这就是两者的区别所在了。

  注意,如果引用的集合修改了集合名称,DBRef引用就无法找到引用的文档了,除非更新所有的DBRef信息。

MongoDB数据关系的表达的更多相关文章

  1. mongoDB 数据导出与导入

    一.导出 命令格式:在mongodb/bin目录下 mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 -f 字段 -q 条件导出 --csv ...

  2. MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  3. 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  4. 开始VS 2012 中LightSwitch系列的第2部分:感受关爱——定义数据关系

    [原文发表地址]  Beginning LightSwitch in VS 2012 Part 2: Feel the Love - Defining Data Relationships [原文发表 ...

  5. MongoDB副本集配置系列十一:MongoDB 数据同步原理和自动故障转移的原理

    1:数据同步的原理: 当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步: 1:检查自己local库的oplog.rs集合找出最近的时间戳. 2:检查Primary ...

  6. mongodb数据文件内部结构

    有人在Quora上提问:MongoDB数据文件内部的组织结构是什么样的.随后10gen的工程师Jared Rosoff出来做了简短的回答. 每一个数据库都有自己独立的文件.如果你开启了director ...

  7. 用elasticsearch索引mongodb数据

    参照网页:单机搭建elasticsearch和mongodb的river 三个步骤: 一,搭建单机replicSet二,安装mongodb-river插件三,创建meta,验证使用 第一步,搭建单机m ...

  8. Mongodb数据备份恢复

    Mongodb数据备份恢复 一.MongoDB数据库导入导出操作 1.导出数据库 twangback为备份的文件夹 命令: mongodump -h 127.0.0.1[服务器IP] -d advie ...

  9. 通过logstash-input-mongodb插件将mongodb数据导入ElasticSearch

    目的很简单,就是将mongodb数据导入es建立相应索引.数据是从特定的网站扒下来,然后进行二次处理,也就是数据去重.清洗,接着再保存到mongodb里,那么如何将数据搞到ElasticSearch中 ...

随机推荐

  1. 量化投资,你需要了解的A股财务数据

    摘要:基本面量化是应用量化研究领域的重头戏,财务数据的整理和加工是基本面量化的第一步.本文梳理了财务数据的基本知识,包括报表类型.数据来源.调整更正和使用原则等,并给出了单季度和TTM数据的计算流程. ...

  2. Java的jdbc调用SQL Server存储过程Bug201906131119

    SQL Server数据库存储过程,一个查询使用动态sql,另一个不使用动态sql,这种情况,jdbc可能获取不到实际查询数据,虽然数据库中执行没问题. 解决方法,都使用静态sql,或都使用动态sql ...

  3. MySQL 实时监控日志

    简单的梳理一下为什么要写这边文章,主要是学了ORM之后,发现通过ORM插入数据真的很方便,但是通过ORM生成的SQL语句又是怎么写的呢,百思不得姐.于是就找到了这个办法 首先查看一下查看MySQL 日 ...

  4. 编写shellcode的几种姿势

    今天开始在做hitcon-training的题目,做到lab2就发现了自己的知识盲区,遇到无法执行shell的情况,需要自己打shellcode执行cat flag 操作 经过一系列的搜索,发现了几种 ...

  5. jQuery绑定动态元素的点击事件无效

    之前就一直受这个问题的困扰,在写ajax加载数据的时候发现,后面追加进来的demo节点元素,失去了之前的点击事件.为什么点击事件失效,我们该怎么去解决呢?那么,我们通过下面的示例简单说明. 示例如下: ...

  6. Java中集合类

    一.Collection Collection 接口用于表示任何对象或元素组.想要尽可能以常规方式处理一组元素时,就使用这一接口.Collection 在前面的大图也可以看出,它是List 和 Set ...

  7. bootstrap 翻页(对齐的链接)

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. Bootstrap历练实例:表单控件状态(禁用)

    禁用的输入框 input 如果您想要禁用一个输入框 input,只需要简单地添加 disabled 属性,这不仅会禁用输入框,还会改变输入框的样式以及当鼠标的指针悬停在元素上时鼠标指针的样式. < ...

  9. ios之UIProgressView

    UIProgressView和UIActivityIndicator有些类似   但是不同之处在于, UIProgressView能够更加精确的反应进度 UIActivityIndicator则只能表 ...

  10. react入门(上)

    1. ReactJS是什么? 1). Facebook开源的一个js库 2). 一个用于动态构建用户界面的js库2. React的特点 * Declarative(声明式编码) * Component ...