MongoDB 一对多关系建模
转文:
本篇博客翻译自:
http://blog.mongodb.org/post/87200945828/6-rules-of-thumb-for-mongodb-schema-design-part-1?mkt_tok=3RkMMJWWfF9wsRonsq7Ldu%2FhmjTEU5z14uUsUKGxhokz2EFye%2BLIHETpodcMTcVnM7zYDBceEJhqyQJxPr3FLdcN0tJuRhTrCw%3D%3D
备注:本译文不是严格意义上的翻译,只是在基于对该原文的理解之上,尽可能表达清楚。如有疑问或不妥,请参考原文。
很多刚从传统SQL开发转向MongoDB开发的朋友都会问到一个问题:如何用MongoDB表达传统关系数据库中的一对多(1 to n)关系?
基于MongoDB丰富的表达力,我们不能说我们必须采用一个标准的方法来进行1 to n的建模。稍后我们从3个具体场景来展开讲解。
首先,我们将1 to n中的n进行场景细化。这个n究竟代表多大的量级呢?是几个到几十个?还是几个到几千个?还是成千上万个?
1) 1 to n(n代表好几个,或几十个,反正不太多)
比如每个Person会有多个Address。此种情况下,我们采用最简单的嵌入式文档来建模。
这种建模的方式包含了显而易见的优点和缺点:
优点:你不需要执行单独的查询就可以获得某个Person的所有Address信息。
缺点:你无法像操作独立文档那样来操作Address信息。你必须首先操作(比如查询)Person文档后,才有可能继续操作Address。
在本实例中,我们不需要对Address进行独立的操作,且Address信息只有在关联到某一个具体Person后才有意义。所以结论是:采用这种embedded(嵌入式)建模是非常适合Person-Address场景的。
2)1 to n(n代表好些个,比如几十个,甚至几百个)
比如产品(Product)和零部件(part),每个产品会有很多个零部件。这种场景下,我们可以采用引用方式来建模,如下:
首先每个part作为单独的文档存在。每个产品中包含一个数组类型字段(parts),这个数组中存放的是所有该产品包含的零部件的编号(_id主键)。当你需要根据某一个产品编号查询该产品包含的所有部件信息时,你可以执行以下操作:
这种建模方式的优缺点也非常明显:
优点:部件是作为独立文档(document)存在的,你可以对某一部件进行独立的操作,比如查询或更新。
缺点:如上,你必须通过两次查询才能找到某一个产品所属的所有部件信息。
在本例中,这个缺点是可以接受的,本身实现起来也不难。而且,通过这种建模,你可以轻易的将1 to n扩展到n to n,即一个产品可以包含多个部件,同时一个部件也可以被多个产品所引用(即同一部件可以被多个产品使用)。
3)1 to n(这个n代表很大的数值,比如成千上万,甚至更大)
比如,每一个机器(host)会产生很大数量的日志信息(logmsg)。在这种情况下,如果你采用嵌入式建模,则一个host文档会非常庞大,从
而轻易超过MongoDB的文档大小限制,所以不可行。如果你采用第二中方式建模,用数组来存放所有logmsg的_id值,这种方式同样不可行,因为当
日止很多时,即使单单引用objectId也会轻易超过文档大小限制。所以此时,我们采用以下方式:
我们在logsmg中,存放对host的_id引用即可。
综上所述,在对1 to n关系建模时,我们需要考虑:
1)n代表的数量级很小,且n代表的实体不需要单独操作时,可以采用嵌入式建模。
2)n代表的数量级比较大,或者n代表的实体需要单独进行操作时,采用在1中用Array存放引用的方式建模。
3)n代表的数量级非常大时,我们没有选择,只能在n端添加一个引用到1端。
MongoDB 一对多关系建模的更多相关文章
- 《Entity Framework 6 Recipes》翻译系列 (5) -----第二章 实体数据建模基础之有载荷和无载荷的多对多关系建模
2-3 无载荷(with NO Payload)的多对多关系建模 问题 在数据库中,存在通过一张链接表来关联两张表的情况.链接表仅包含连接两张表形成多对多关系的外键,你需要把这两张多对多关系的表导入到 ...
- 数据库建模软件ERStudio-表关系建模详解
ERStudio是优秀的数据库建模软件,它不仅可以建立表.视图等模型,还可以建立多表间各种关系的模型,另外还可以根据模型生成表到数据库,下面具体讲解一下它的表关系建模. 1. 首先讲一下怎么建立表关系 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (10) -----第二章 实体数据建模基础之两实体间Is-a和Has-a关系建模、嵌入值映射
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-11 两实体间Is-a和Has-a关系建模 问题 你有两张有Is-a和Has-a ...
- 10.Configure One-to-Many(配置一对多关系)【Code-First系列】
现在,我们将学习怎么配置一对多的关系. Visit Entity Relationship section to understand how EF manages one-to-one, one-t ...
- Mybatis框架中实现双向一对多关系映射
学习过Hibernate框架的伙伴们很容易就能简单的配置各种映射关系(Hibernate框架的映射关系在我的blogs中也有详细的讲解),但是在Mybatis框架中我们又如何去实现 一对多的关系映射呢 ...
- [NHibernate]一对多关系(级联删除,级联添加)
目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...
- [NHibernate]一对多关系(关联查询)
目录 写在前面 文档与系列文章 一对多查询 总结 写在前面 上篇文章介绍了nhibernate的一对多关系如何配置,以及级联删除,级联添加数据的内容.这篇文章我们将学习nhibernate中的一对多关 ...
- [Fluent NHibernate]一对多关系处理
目录 写在前面 系列文章 一对多关系 总结 写在前面 上篇文章简单介绍了,Fluent Nhibernate使用代码的方式生成Nhibernate的配置文件,以及如何生成持久化类的映射文件.通过上篇的 ...
- hibernate中一对多关系中的inverse,cascade属性
举例说明: 一对多关系的两张表:boy.girl(一个男孩可以多个女朋友) boy表结构 Field Type ------ ----------- name varcha ...
随机推荐
- JAVA开发-我的第一个webScan扫描器
写的第一句话就是感谢shack2,参考了他的代码知道原来有的解耦可以这样写,但是又在他的基础上改写了很多. 代码分享给大写,下面是程序的截图,我把他取名为:HadesWebScan ps:Wind ...
- EntityFramework 开始小试
1 Install-Package EntityFramework 2 创建实体类 public class Blog { public int BlogId { get; set; } public ...
- hdu 4946 Area of Mushroom(凸包)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 Area of Mushroom Time Limit: 2000/1000 MS (Java/Ot ...
- Linux Shell脚本攻略 读书笔记
Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...
- [转]-Gradle使用手册(一):为什么要用Gradle?
原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Using-sourceCompatibility-1. ...
- 关于C++类中的成员
突然发现,如果C++的类成员中存在共有的成员,则可以通过指针的偏移来访问私有的成员变量,当然前提是对内存对齐比较清楚.只要骗过了编译器就可以为所欲为了. #include <cstdio> ...
- z-score
标准分数(standard score)也叫z分数(z-score),是一个分数与平均数的差再除以标准差的过程.用公式表示为: z=(x-μ)/σ.其中x为某一具体分数, μ为平均数,σ为标准差. Z ...
- Ruby方法
Ruby 方法 Ruby 方法与其他编程语言中的函数类似.Ruby 方法用于捆绑一个或多个重复的语句到一个单元中. 方法名应以小写字母开头.如果您以大写字母作为方法名的开头,Ruby 可能会把它当作常 ...
- 20160808_Linux服务
1. http://bbs.csdn.net/topics/370100269 2. http://blog.csdn.net/csfreebird/article/details/8239933 h ...
- 任务调度quartz
http://www.cnblogs.com/cnjava/archive/2013/02/28/2937291.html