虽说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. 原生js格式化json的方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. CAD命令标志

    CAD命令标志 主标识:(常用的)ACRX_CMD_MODAL 在别的命令执行的时候该命令不会在其中执行.ACRX_CMD_TRANSPARENT 命令可以再其它命令中执行,但在该标志下ads_sss ...

  3. Shift-Invariant论文笔记

    ICML 2019 Making Convolutional Networks Shift-Invariant Again ICML 2019 Making Convolutional Network ...

  4. Jarvis OJ-level3

    使用ret2libc攻击方法绕过数据执行保护 from pwn import* conn = remote("pwn2.jarvisoj.com",9879) elf = ELF( ...

  5. shell脚本,通过传入的参数来计算最大值和最小值以及平均值。

    [root@localhost zuoye]# cat quansges.sh #!/bin/bash > file [ ! $# -ge ] && || echo $* > ...

  6. solr 单机模式搭建

    系统环境:centos 7 安装前准备 安装JDK环境 下载tomcat.solr安装包:solr下载地址:http://archive.apache.org/dist/lucene/solr/ 安装 ...

  7. python基础知识13-迭代器与生成器,导入模块

    异常处理作业讲解 file = open('/home/pyvip/aaa.txt','w+') try: my_dict = {'name':'adb'} file.write(my_dict['a ...

  8. uboot-imx RGB24分析

    在mx6q_sabrsd.c文件中 函数else if(strcmp(s, "YUV444") == 0) val = IPU_PIX_FMT_YUV444; else val = ...

  9. sublime__最全面的 Sublime Text 使用指南

    感谢大佬--> 原文链接 摘要(Abstract) 本文系统全面的介绍了Sublime Text,旨在成为最优秀的Sublime Text中文教程. 前言(Prologue) Sublime T ...

  10. Robotium测试没有源码的apk--需重签名apk

    Robotium是基于Instrumentation框架的,其编写的测试脚本与被测程序运行在同一个进程里面,所以这需要测试程序与被测程序拥有相同的签名,否则无法进行通讯.在只有apk的情况下可以采用“ ...