原文: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集合中,数据趋向顺序的存储在磁盘上。因此,集合的表扫描是会发生的效率问题。集合的高吞吐批处理是非常重要的。
分享到:
相关推荐
作者:赵静,多年互联网领域从业经验,现服务于Maxleap基础服务及架构组,主要负责云数据(CloudData)架构设计及研发,关注分布式计算、云存储。
IoT系统中的MongoDB架构设计.pptx
项目目标是设计和实施可用于在第三方网页上集成的实时聊天工具。 一些参数已预设,一些参数随附。 一些模块需要额外的查询,例如统计。 项目已实施并记录在案,并提出了改进代码集成的建议。 复制数据的建议。 附加...
同时Mongodb开发者在Command上又做了非常清晰体系架构和设计,便于管理和高效执行各种类型的Command。今天就专门用一篇篇幅来着重介绍一下其Command的体系架构,并用例子来介绍mongod是如何将Command引入其中的。...
基于大叔bob clean架构的服务器设计 从内圈向外的包依赖项: 领域 数据模型定义和接口 接口.repositories 域接口的实现。 DB 是 mongo 用例 应用程序用例实现。 还定义了跨用例和 web 控制器使用的数据类型 基础...
系统以Windows操作系统为平台,网络联接以TCP/IP协议为基础,使用Web服务器提供信息的浏览和查询,采用流行的B/S架构。根据购物系统的特点,本网站设计了前台和后台两个模块: 系统前台,主要实现了用户信息的注册,...
第七课MySQL数据库设计.pdf 第三十一课percona-toolkits 的实战及自动化.pdf 第三课MySQL授权认证.pdf 第九课MySQL字符集.pdf 第二十一课MySQL常见错误-converted.pdf 第二十课MySQL索引和调优.pdf 第二课...
Maven,Spark和Freemarker第2周:CRUD Mongo Shell,查询运算符,更新运算符和一些命令第三周:架构设计模式,案例研究与权衡第四周:表演使用索引,监视和了解性能。 分片环境中的性能第五周:聚合框架目标,管道...
该站点遵循MVC设计模式(模型-视图-控制器),这是软件公司常用的开发体系结构样式。 部署的站点@ 安装要求 通过输入以下命令在命令行中克隆我的投资组合:git clone 通过在命令行中输入来安装所需的库:npm i ...
哲学MongoKit设计为: 简单:MongoKit使用普通的python类型来描述文档结构fast :MongoKit很快,但是如果您确实需要很快,则无需更改API即可访问原始pymongo层功能强大:MongoKit带来许多功能,例如文档自动引用,...
chapin blog微服务架构 & DevOpsK8SService Mesh苏槐系列文章如何快速搭建一个微服务架构微服务架构中API的开发与治理如何保障无服务架构下的数据一致性使用Docker来支撑微服务架构部署及维护架构设计系统设计入门...
MongoDB Playgrounds是直接在VS Code内部对CRUD操作和其他MongoDB命令进行原型设计和执行的最便捷方法。 使用MongoDB语法突出显示和智能自动完成功能为MongoDB Shell API,MongoDB运算符以及数据库,集合和字段名称...
注意:填充是一项强大的功能,但它有局限性,可以帮助您摆脱不良的架构设计。 特别是,MongoDB模式设计通常会很糟糕,因为它会包含增长而不受约束的数组。 请勿在架构中包括一个不断增长的ObjectId数组-随着数组的...
洋葱架构启动项目代号:inbiz-onion背景该项目旨在通过领域驱动开发(DDD)提供非常基本和直接的洋葱架构采用。 它是一个分层项目,请随时更改以适应您的业务需求。交叉关注点缓存异常记录通知实施技术为了演示目的...
软件架构 1.前端模板:Layui Fly Template 2.Flask + flask-pymongo + flask-admin + flask-login + flask-mail 使用说明 首次打开会自动往MongoDB新增一些默认数据(管理员账号和默认配置项),后台管理(flask-...
mongo mysql php lumen laravel thinkphp opencart 互联网 技术革命 跨境电商 流量运营 性能监控 开发工具 编码与解码 渗透与网络 ip 设计与原型 下载工具 api cdn IDE&Editor vim vs tampermonkey 浏览器 weixin ...
什么是Refract-CMS? Refract-CMS是使用React,Express和MongoDB的开源,代码优先,自托管的无头CMS。 ... 干净的数据库,Refract-CMS每个架构仅创建一个mongo集合,因为它不必在其中存储架构信息