简介
MongoDB并不是在实验室中的环境中设计的。我们是根据构建可伸缩,高可用,灵活系统的实际经验来构建MongoDB。我们并不是从头开始的,我们要去发现问题并去解决。因此我设想如果你要取代MySQL以及要改变关系模型,你可以选择MongoDB,并获得很多很好的特性:为了速度而优化的嵌入文档(embedded docs),可管理的,灵活schema数据库的敏捷开发,因为没有join,所以更加容易水平扩展。也有很多关系型数据库的优势:索引,动态查询以及更新等等,并且使用方式并没有改变什么。举个例子,在MongoDB中,设计索引的方法和MySQL或者Oracle基本一致,你仅仅要在内嵌字段索引上做个选择。
为什么选择MongoDB?
- 面向文档的存储
- 文档(对象)能更好的映射编程语言的数据类型
- 内嵌文档和数组可以减少join的需求
- 动态字段更容易schema的扩展
- 没有join以及事务处理,性能会更好,可扩展性更强
- 高性能
- 没有join和嵌入会使读写更为迅速
- 支持嵌入文档和数组的索引
- 可选择异步的写入
- 高可用
- 支持复制,并且支持主服务器的自动切换
- 容易扩展
- 自动sharding(把数据水平扩展到很多服务器上)
- 数据的读写分布于shards上
- 没有join和事务可以使分布式查询更为快速
- 最终一致性的读取数据可以分布于复制的服务器上。
- 自动sharding(把数据水平扩展到很多服务器上)
- 丰富的查询语言
大型MongoDB的部署
1.一个或者多个shards,每个shard保存了部分数据(自动管理)。读取和写入自动的被路由到适合的shards。每个shard都可以使用复制集(replica set)-当然复制的数据仅仅是那个shard保存的数据。
一个复制集(replica set)是由一个或者多个服务器组成,每个服务器都保存一些数据的拷贝。在给定的时间范围内,一个是主并且剩下的为候选。如果主挂掉了,候选的会自动变为主。所有的写入和一致性的读都会访问主,并且所有最终一致性的读会分布于其他的候选服务器上。
2. 多个配置服务器(config servers), 每个配置服务器都保存data的基础信息,如哪些数据保存在哪些shard。
3. 一个或者多个路由(routers),对于一个或多个客户端来说,每个都作为一个服务器。客户端的查询/更新都是通过这个路由并且路由通过配置服务器的存储的信息再把它们路由给适合的shard。
4.一个或多个客户端,每一个都是用户的应用(或者部分是)并且通过MongoDB提供相应的语言包发送命令给路由。
mongod 是服务端程序 (数据或者配置服务器). mongos 是路由程序.
Mongo的数据模型
- 一个Mongo 系统(看如上的部署)包含了一组数据库
- 一个database包含了一组collection(集合)
- 一个collelction包含了一组document(文档)
- 一个document包含了一组字段
- 一个字段就是一个key-value对
- key是名字
- value可以是如下
- 基本类型,如string,integer,float,timestamp,binary,等。
- 一个document或者
- 一数组的value
Mongo 查询语言
从一个db的collection重获取想要的documents,你要做的就是一个查询document的字段要和需要document字段相吻合。如,{name: {first: 'John', last: 'Doe'}} 会匹配上所有名字为John Doe的document。同样的{name.last: 'Doe'}会匹配last name为Doe的所有文档。同样的, {name.last: /^D/}会匹配所有last name以D开头字母的document(/^D/正则表达式)。查询语句也可以匹配嵌入数组(embedded arrays)。如{keywords: 'storage'}会匹配keywords数组包含storage的所有document。同样的,{keywords: {$in: ['storage', 'DBMS']}},会匹配数组包含storage或者DBMS的documents。
如果一个collection有很多的documents并且你想快速的查到所需要的document,那么就创建索引吧。举个例子,索引语法是ensureIndex({name.last: 1}) 或者ensureIndex({keywords: 1})。注意,索引需要更多的硬盘空间并且会降低写入的速度,因此要恰当的使用索引。