`
songgz
  • 浏览: 38883 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Mongo架构设计

阅读更多
原文: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集合中,数据趋向顺序的存储在磁盘上。因此,集合的表扫描是会发生的效率问题。集合的高吞吐批处理是非常重要的。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics