

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是其支持的查询语言非常强大,而语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB (from "humongous") is a scalable, high-performance, open source, document-oriented database. Written in C++.
它的特点是高性能、易部署、易使用,存储数据非常方便,主要功能特性有:
* 面向集合存储,易存储对象类型的数据。
* 模式自由。
* 支持动态查询。
* 支持完全索引,包含内部对象。
* 支持查询。
* 支持复制和故障恢复。
* 使用高效的二进制数据存储,包括大型对象(如视频等)。
* 自动处理碎片,以支持云计算层次的扩展性。
* 支持PERL,RUBY,PYTHON,JAVA,C++,PHP等多种语言。
* 文件存储格式为BSON(一种JSON的扩展) 。
* 可通过网络访问。
整体架构:
内部架构:
所谓“面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。 存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各中复杂的文件类型。我们称这种存储形式为BSON(Binary Serialized dOcument Format)。
MongoDB服务端可运行在Linux、Windows或OS X平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB。MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。
MongoDB与CouchDB全面对比
MongoDB与CouchDB很相似,他们都是文档型存储,数据存储格式都是JSON型的,都使用Javascript进行操作,都支持Map/Reduce。但是其实二者有着很多本质的区别,下面将透过现象追寻本质,让你更好的理解MongoDB与CouchDB。
1.MVCC(Multiversion concurrency control)
MongoDB与CouchDB的一大区别就是CouchDB是一个MVCC的系统,而MongoDB是一个update-in-place的系统。这二者的区别就是,MongoDB进行写操作时都是即时完成写操作,写操作成功则数据就写成功了,而CouchDB一个支持多版本控制的系统,此类系统通常支持多个结点写,而系统会检测到多个系统的写操作之间的冲突并以一定的算法规则予以解决。
2.水平扩展性
在扩展性方面,CouchDB使用replication去做,而MongoDB的replication仅仅用来增强数据的可靠性,MongoDB在实现水平扩展性方面使用的是Sharding(据说CouchDB也有开发分片功能的计划) 。
3.数据查询操作
这个区别在用户接口上了,MongoDB与传统的数据库系统类似,支持动态查询,即使在没有建立索引的行上,也能进行任意的查询。而CouchDB不同,CouchDB不支持动态查询,你必须为你的每一个查询模式建立相应的view,并在此view的基础上进行查询。
4.原子性
这一点上两者比较一致,都支持针对行的原子性修改(concurrent modifications of single documents),但不支持更多的复杂事务操作。
5.数据可靠性
CouchDB是一个"crash-only"的系统,你可以在任何时候停掉CouchDB并能保证数据的一致性。而MongoDB在不正常的停掉后需要运repairDatabase()命令来修复数据文件,在1.7.5版本后支持单机可靠的–dur命令。
6.Map/Reduce
MongoDB和CouchDB都支持Map/Reduce,不同的是MongoDB只有在数据统计操作中会用到,而CouchDB在变通查询时也是使用Map/Reduce。
7.使用 javascript
MongoDB和CouchDB都支持javascript,CouchDb用javascript来创建view。MongoDB使用JSON作为普通数据库操作的表达式。当然你也可以在操作中包含javascript语句。MongoDB还支持服务端的javascript脚本(running arbitrary javascript functions server-side),当然,MongoDB的Map/Reduce函数也是javascript格式的。
8.REST
CouchDB是一个RESTFul的数据库,其操作完全走HTTP协议,而MongoDB是走的自己的二进制协议。MongoDB Server在启动时可以开放一个HTTP的接口供状态监控。
9.性能
此处主要列举了MongoDB自己具有高性能的原因
采用二进制协议,而非CouchDB REST的HTTP协议
使用Momary Map内存映射的做法
collection-oriented,面向集合的存储,同一个collection的数据是连续存储的
update-in-place直接修改,而非使用MVCC的机制
使用C++编写
10.适用场景
如果在构建一个 Lotus Notes型的应用,我们推荐使用CouchDB,主要是由于它的MVCC机制。另外如果我们需要master-master的架构,需要基于地理位置的数据分布,或者在数据结点可能不在线的情况下,我们推荐使用CouchDB。 若需要高性能的存储服务,那推荐MongoDB,比如用于存储大型网站的用户个人信息,比如用于构建在其它存储层之上的Cache层。如果你的需求中有大量update操作,那么使用MongoDB吧。就像我们在例子updating real time analytics counters中的一样,对于那种经常变化的数据,比如浏览量,访问数之类的数据存储。
MongoDB 更改开源协议
2018年10月18日,据 TechCrunch 的报道:部分云计算公司在使用 MongoDB 的时候没有遵循其开源协议,MongoDB 为应对此类问题,选择将其开源许可证从 GNU AGPLv3 切换到 Server Side Public License (SSPL),即服务器端公共许可证,"它将适用于其 MongoDB 社区服务器的所有新版本,以及先前的所有补丁修复版本。"
许可证更改并不影响当前使用社区服务器的常规用户。根据 MongoDB 之前的 GNU AGPLv3 协议,想要将 MongoDB 作为公共服务运行的公司必须将他们的软件开源,或需要从 MongoDB 获得商业许可,该公司解释说,"然而,MongoDB 的普及使一些组织在违反 GNU AGPLv3 协议的边缘疯狂试探,甚至直接违反了协议。"
尽管 SSPL 与 GNU GPLv3 没有什么不同,但 SSPL 会明确要求托管 MongoDB 实例的云计算公司要么从 MongoDB 获取商业许可证,要么向社区开源其服务代码。MongoDB 所采用的 SSPL 协议不是 OSI 批准的开源许可协议。SSPL(Server Side Public License) 是服务器端公共许可证,它适用于其 MongoDB 社区服务器的所有新版本,以及先前的所有补丁修复版本。
最新版本:3.2
主要新特性包括:
可插入式的存储引擎 API
支持 WiredTiger 存储引擎
MMAPv1 提升
复制集全面提升
集群方面的改进
提升了安全性
工具的提升
详细介绍请看发行说明。
最新版本:4.2
MongoDB 首席技术官 Elliot Horowitz 说,新版本带来了一些特性,主要有以下几点:
通配符索引:可以在子文档上创建索引,使读取速度更快
搜索引擎集成:这是一个非常简单且好用功能,给应用程序提供一个良好的搜索工具
新的更新命令语法:开发人员可以使用 MongoDB 查询语言从 Amazon S3 查询任何格式的数据(JSON、BSON、CSV、TSV、Avro和Parquet 等)
字段级加密:通过在驱动程序中提供字段级加密或客户端加密,数据库服务器只看到密文,而不能知道任何密钥。
除了这些特性之外,还有例如按需物化视图、表达式视图、Agg Pipeline ++、zStandard 压缩、分布式事务和对Kubernetes的支持等。
最新版本:5.0
MongoDB 5.0 正式版于2021年7月中旬发布,该版本部分更新内容如下:
时间序列集合:5.0中引入了时间序列集合,它有效地存储了一段时期内的测量序列。与普通集合相比,在时间序列集合中存储时间序列数据可以提高查询效率,并减少数据和索引的磁盘使用。
聚合
新的聚合操作符,MongoDB 5.0 引入了以下聚合操作:
$count: $count 在现有管道 $group 阶段和新的 MongoDB 5.0 $setWindowFields 阶段中使用时,提供所有文档的计数。
$dateAdd: 将一个 Date 对象按指定的时间单位递增。
$dateDiff: 返回两个日期之间的差异。
$sampleRate: 添加 $sampleRate 方法,以给定的速度从管道中概率性地选择文档。
$rand: 每次调用 $rand 方法时,都会生成一个0到1之间的随机浮点数。新的 $sampleRate 操作是基于 $rand 的。
窗口操作符:5.0 引入了 $setWindowFields 管道阶段,允许你在一个集合中的指定跨度的文档上执行操作,称为窗口。该操作根据所选择的窗口操作符返回结果。
一般聚合的改进
$expr 操作符:比较运算符使用索引,从 5.0 开始,放在 $expr 操作符中的 $eq、$lt、$lte、$gt和 $gte 操作符可以使用索引来提高性能。
$ifNull 表达式接受多个输入表达式:从 MongoDB 5.0 开始,在返回一个替换表达式之前,你可以为 $ifNull 表达式指定多个输入表达式。
聚合的 let 选项:从 MongoDB 5.0 开始, aggregate 命令和 db.collection.aggregate() 辅助方法有一个 let 选项,用于指定一个可以在聚合管道的其他地方使用的变量列表。这允许你通过将变量与查询文本分开来提高命令的可读性。
$lookup 阶段:简洁的相关子查询,从 MongoDB 5.0 开始,聚合管道 $lookup 阶段支持简明的相关子查询,改善集合之间的连接。
变更事件输出:从 MongoDB 5.0 开始,变更事件包含字段 updateDescription.truncatedArrays 来记录数组的截断。
索引
删除了 geoHaystack 索引和 geoSearch 命令:5.0 删除了废弃的 geoHaystack 索引和 geoSearch 命令。使用带有 $geoNear 的 2d 索引或支持的 geospatial 查询操作符来代替。将 MongoDB 实例升级到 5.0 并将 featureCompatibilityVersion 设置为 5.0 将删除任何先前存在的 geoHaystack 索引。
新的错误信息:db.collection.createIndex() 和 db.collection.createIndexes() 操作在选项指定不正确时有新的错误信息。
中断索引构建:如果副本集中的一个节点在索引构建过程中完全关闭或回滚,索引构建的进度现在会被保存到磁盘上。当服务器重新启动时,索引创建将从保存的位置恢复。
reIndex行为改变:从 MongoDB 5.0 开始,reIndex命令和 [db.collection.reIndex()] shell 方法只能在独立实例上运行 。
安全
支持配置 TLS 1.3 密码套件,MongoDB 5.0引入了opensslCipherSuiteConfig参数,以便在使用TLS 1.3加密时,能够配置OpenSSL所支持的密码套件。
完整的更新文档可查看此处。
官方主页:http://www.mongodb.org/