MongoDB是一款强大、灵活,且易于扩展的通用型数据库。它能扩展出非常多的功能,如二级索引(secondary index)、范围查询(range query)、排序、聚合(aggregation),以及地理空间索引(geospatial index)。本章涵盖了MongoDB的主要设计特点。
1.1 易于使用
MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库。不采用关系模型主要是为了获得更好的扩展性。当然, 还有其他一些好处。
与关系型数据库相比,面向文档的数据库不再有“行”(row)的概念,取而代之的是更为灵活的“文档”(document)模型。通过在文档中嵌入文档和数组,面向文档的方法能够仅使用一条记录来表现复杂的层次关系,这与使用现代面向对象语言的开发者对数据的看法一致。
另外,不再有预定义模式(predefined schema):文档的键(key)和值(value)不再是固定的类型和大小。由于没有固定的模式,根据需要添加或删除字段变得更容易了。通常,由于开发者能够进行快速迭代,所以开发进程得以加快。而且,实验更容易进行。开发者能尝试大量的数据模型,从中选择一个最好的。
1.2 易于扩展
应用程序数据集的大小正在以不可思议的速度增长。随着可用带宽的增长和存储器价格的下降,即使是一个小规模的应用程序,需要存储的数据量也可能大得惊人,甚至超出了很多数据库的处理能力。过去非常罕见的T级别数据,现在已是司空见惯了。
由于需要存储的数据量不断增长,开发者面临一个困难:应该如何扩展数据库?实质上,这是纵向扩展(scale up)和横向扩展(scale out)之间的选择。纵向扩展就是使用计算能力更强的机器,而横向扩展就是通过分区将数据分散到更多机器上。通常,纵向扩展是最省力的做法,其缺点是大型机一般都非常昂贵。而且,当数据量达到机器的物理极限时,无论花多少钱也买不到更强的机器了。另一个选择是横向扩展:要增加存储空间或提高性能,只需购买一台普通的服务器并把它添加到集群中就可以了。横向扩展既便宜又易于扩展;不过,管理1000台机器比管理一台机器显然要困难得多。
MongoDB的设计采用横向扩展。面向文档的数据模型使它能很容易地在多台服务器之间进行数据分割。MongoDB能自动处理跨集群的数据和负载,自动重新分配文档,以及将用户请求路由到正确的机器上。这样,开发者能够集中精力编写应用程序,而不需要考虑如何扩展的问题。如果一个集群需要更大的容量,只需要向集群添加新服务器,MongoDB就会自动将现有数据向新服务器传送。
1.3 丰富的功能
MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供一系列不断扩展的独特功能。
索引(indexing)
MongoDB支持通用二级索引,允许多种快速查询,且提供唯一索引、复合索引、地理空间索引,以及全文索引。 
聚合(aggregation)
MongoDB支持“聚合管道”(aggregation pipeline)。用户能通过简单的片段创建复杂的聚合,并通过数据库自动优化。
特殊的集合类型
MongoDB支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话(session)。类似地,MongoDB也支持固定大小的集合,用于保存近期数据,如日志。
文件存储(file storage)
MongoDB支持一种非常易用的协议,用于存储大文件和文件元数据。
MongoDB并不具备一些在关系型数据库中很普遍的功能,如连接(join)和复杂的多行事务(multirow transaction)。省略这些功能是出于架构上的考虑(为了得到更好的扩展性),因为在分布式系统中这两个功能难以高效地实现。
1.4 卓越的性能
MongoDB的一个主要目标是提供卓越的性能,这很大程度上决定了MongoDB的设计。MongoDB能对文档进行动态填充(dynamic padding),也能预分配数据文件以利用额外的空间来换取稳定的性能。MongoDB把尽可能多的内存用作缓存(cache),试图为每次查询自动选择正确的索引。总之,MongoDB在各方面的设计都旨在保持它的高性能。
虽然,MongoDB非常强大并试图保留关系型数据库的很多特性,但它并不追求具备关系型数据库的所有功能。只要有可能,数据库服务器就会将处理和逻辑交给客户端(通过驱动程序或用户的应用程序代码来实现)。这种精简方式的设计是MongoDB能够实现如此高性能的原因之一。
1.5 小结
本书将详细说明MongoDB开发过程中的一些特定设计背后的原因和动机,借此分享MongoDB背后的哲学。当然,掌握MongoDB最好的方式是创建一个易扩展、灵活、快速的功能完备的数据存储,这也是MongoDB的意义所在。