MongoDB数据关系的表达
虽说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数据关系的表达的更多相关文章
- mongoDB 数据导出与导入
一.导出 命令格式:在mongodb/bin目录下 mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 -f 字段 -q 条件导出 --csv ...
- MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据
看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...
- 在MVC模式下通过Jqgrid表格操作MongoDB数据
看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...
- 开始VS 2012 中LightSwitch系列的第2部分:感受关爱——定义数据关系
[原文发表地址] Beginning LightSwitch in VS 2012 Part 2: Feel the Love - Defining Data Relationships [原文发表 ...
- MongoDB副本集配置系列十一:MongoDB 数据同步原理和自动故障转移的原理
1:数据同步的原理: 当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步: 1:检查自己local库的oplog.rs集合找出最近的时间戳. 2:检查Primary ...
- mongodb数据文件内部结构
有人在Quora上提问:MongoDB数据文件内部的组织结构是什么样的.随后10gen的工程师Jared Rosoff出来做了简短的回答. 每一个数据库都有自己独立的文件.如果你开启了director ...
- 用elasticsearch索引mongodb数据
参照网页:单机搭建elasticsearch和mongodb的river 三个步骤: 一,搭建单机replicSet二,安装mongodb-river插件三,创建meta,验证使用 第一步,搭建单机m ...
- Mongodb数据备份恢复
Mongodb数据备份恢复 一.MongoDB数据库导入导出操作 1.导出数据库 twangback为备份的文件夹 命令: mongodump -h 127.0.0.1[服务器IP] -d advie ...
- 通过logstash-input-mongodb插件将mongodb数据导入ElasticSearch
目的很简单,就是将mongodb数据导入es建立相应索引.数据是从特定的网站扒下来,然后进行二次处理,也就是数据去重.清洗,接着再保存到mongodb里,那么如何将数据搞到ElasticSearch中 ...
随机推荐
- Asp.Net Core 入门(十)—— 模型绑定和验证
模型绑定时将Http请求中的数据映射到控制器操作方法上对应的参数,操作方法中的参数可以是简单类型,如整形,字符串等,也可以是复杂类型,如Product,Order等. Asp.Net Core MVC ...
- python已安装好第三方库,pycharm import时仍标红的解决办法
pip install pymysql之后导入import pymysql时候标红 发现 pymysql下方还是标红,不能正常导入 可以试用一下以下的办法 解决办法: 首先打开 Settings找到P ...
- shell脚本,提取ip地址和子网掩码,和查外网ip地址信息。
#提取IP地址和子网掩码 [root@localhost ~]# ifconfig eth0|grep 'inet addr'|awk -F'[ :]+' '{print $4"/& ...
- 看结果,测试?java中的String类 字符串拆分成字符串数组 判定邮箱地址 字符串比较 参数传递?
看结果1? package com.swift; class ArrayString { public static void main(String[] args) { String str = & ...
- 基于Passthru的NDIS开发的个人理解
这几天对NDIS的学习,基本思路是:首先熟悉理论知识→然后下载一个例子进行研究→最后例子自己模仿扩展→最最后尝试自己写一个新的. Passthru是微软NDIS自己写的一个框架驱动,NDIS开发者可以 ...
- 气泡小角的css实现
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> ...
- laravel中的gate
public function boot(){ $this->registerPolicies(); Gate::define('update-post',function($user,$pos ...
- 记我的小网站发现的Bug之一 —— 某用户签到了两次
1.故事背景 今天上午我忙完手中的事情之后突然想起来我还没签到,于是赶紧打开签到页面,刚点击了签到按钮,提示"签到成功,获得25阅读额度!",正准备退出浏览器,忽然发现签到列表有异 ...
- PAT Basic 1018
1018 锤子剪刀布 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入格式: 输 ...
- MFC中的CListControl控件
一直想要这种效果,无奈刚开始用了cListbox控件,不知道怎么生成背景的边框,找了好久资料,突然发现好像控件用错了. 用CListControl控件实现图中效果,超级开心~ 实现过程: 添加一个Li ...