设为首页 收藏本站
查看: 1142|回复: 0

[经验分享] Mongo架构设计

[复制链接]

尚未签到

发表于 2016-12-2 07:42:16 | 显示全部楼层 |阅读模式
原文:http://www.mongodb.org/display/DOCS/Schema+Design
架构设计

  • 介绍
  • 比较嵌入和引用
  • 用例
  • 选择索引
  • 多少集合?


介绍

相对于设计一个关系型架构,使用Mongo不需做“规范化”,因为没有服务器边的“joins”。一般来说,希望每一个顶级对像对应一个数据库集合。
不必每个类一个集合,代之以嵌入对像。例如,在下面的图中,有两个集合,students和courses。

Student文档嵌入address文档和其中有courses引用的score文档。
对比关系型架构,几乎总是放置scores到一个单独表,并且此表有一个外键关联到students表。

比较嵌入和引用

在Mongo 架构设计里的关键问题是“这个对像是否值得作为一个集合,更确切地说,它应该嵌入到其它集合吗?”在关系型数据库中,每一个重要的子项通常作为一个单独的表(除非出于性能考虑)。在Mongo中,这是不推荐使用的--嵌入对像是更有效率的。然后同位数据在磁盘上,客户机--服务器周转到数据库被淘汰。因此,通常的疑问是,“为什么不想嵌入这个对像?”
为什么引用是慢的?考虑students的例子。如果有一个student对像,并执行:
print( student.address.city );
这个操作将无疑是快的,因为address是一个嵌入对像并且一直在内存中,如果student在内存中。然而,对于:
print( student.scores[0].for_course.name );
如果这是首次访问scores[0],shell或你的驱动必须执行查询
/ /伪代码的驱动程序或框架,而不是用户代码
student.scores[0].for_course = db.courses.findOne({_id:_course_id_to_find_});
因此,每个引用遍历一次数据库的查询。通常的考虑是在这个集合上建一个_id索引。如此,该查询将是很快的。然而,即使全部数据都在内存中,也存在隐式的从应用服务器到数据库服务器的数据通信。在一般情况下,期望一个在内存缓存中的查询时间为1毫秒。因此,如果我们遍历1000名学生,通过引用查找每个学生将非常缓慢 - 执行时间超过1秒,即使从缓存中。然而,如果我们只需要查找单个项目,时间为1ms的秩序,为网页完全加载可以接受的。(注意,如果已经在数据库缓存中,取出1000名学生可能实际花销远低于1秒,因为结果集从数据库成批返回。)

关于何时嵌入和何时引用的一般规则:

  • 处于顶级的“首类”对像一般有自己的集合。
  • 用于明细的条目对像一般使用嵌入。
  • 对像跟对像建模为“包含”关系通常将被嵌入。
  • 多对多关系通常使用引用。
  • 只有少数集合可能单独固定存在,因为整个集合很快被缓存到应用服务器内存。
  • 在集合里,与“顶级”对像相比嵌入对像是无法引用,因为不能有一个DBRef对于一个嵌入对像(至少没有)。
  • 在系统层次展现嵌入对象是困难的。
  • 例如,如果Scores不是嵌入的,查询全部students的前100个scores。
  • 如果嵌入大量数据(许多兆字节),就会达到单个对像的大小限制。
  • 如果考虑性能则嵌入。


用例

现在考虑几个用例。
Customer / Order / Order Line-Item
Orders将是一个集合。Customers也是一个集合。Line-items 将是一个line-items数组被嵌入到order对像。
博客系统。
Posts将是一个集合。在Post里作者可以是一个单独的集合或是一个简单的字段,如同只是一个email地址。为了性能,在post内comments对像将是嵌入的。

选择索引

架构设计的第二个方面是选择索引。一般来说,在关系数据库中怎么选,在Mongo中同样怎么选。

  • _id字段自动被索引。
  • 用于关键字查找的字段应设为索引。
  • 通常排序字段应设为索引。

MongoDB压测器(profiler)提供详细的信息,给出已添加的那个索引是错误的。
注意,加入索引会使写入集合变慢,但是读除外。大多数索引用于读写比率高的集合(假设不介意耗费存储空间)。对使用索引的集合做写操作比做读操的开销要多。

多少集合?

Mongo集合是多态的,它可以放入任何对像!对像数据库采取这种方式。因为性能的原因,我们不推荐这种方式。在Mongo集合中,数据趋向顺序的存储在磁盘上。因此,集合的表扫描是会发生的效率问题。集合的高吞吐批处理是非常重要的。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-308343-1-1.html 上篇帖子: mongo第二天 下篇帖子: php操作mongo
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表