MongoDB数据关系的表达

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

一、文档嵌套

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

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

 

二、数据库引用

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

1. 手动引用

  这种方式比较简单,有点类似Mysql的外键功能。比如现在有两个集合:usersarticle,在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信息。

 

转载于:https://www.cnblogs.com/wujuntian/p/8399642.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值