OPTIONS
翻译或纠错本页面

FAQ: MongoDB基础知识

这篇文档讲述了一些概略性的MongoDB问题及其使用。

假如你没有发现你想要的答案,可以看一下这个页面: complete list of FAQs 或者把你问题发布到 MongoDB User Mailing List.

MongoDB是个什么样的数据库?

MongoDB是一个文档型的数据库。和MySQL类似但是用JSON作为数据模型,而不是关系型表。MongoDB不支持关联或者强事务。但是MongoDB支持二级索引,丰富的查询语法,在文档级别有原子性写操作,读操作有很好的一致性。

在部署方面,MongoDB支持Master-Slave的复制方式,支持自动failover和以分布数据方式进行水平扩展。

注解

MongoDB使用BSON,一种和JSON类似但是比JSON更高效的二进制对象格式,作为存储方式。

MongoDB有表吗?

MongoDB数据库用:term:集合 collections <collection> 来组织文档,类似于关系型数据库的表。一个集合内可以有一个或多个:term:文档 documents <document>。文档的概念类似于关系型数据库的一个行,但是有更完整的信息。每个文档有多个字段,一个字段和关系型的一个列类似。

集合和RDBMS的表很不相同。一个集合内的文档可能会有不同的字段和结构。你可以只对某些文档增加一个字段,而不是所有的文档。

MongoDB需要模式(schema)吗?

MongoDB使用动态模式。你可以建立一个没有预定义模式的集合。你可以通过直接在文档内增加或删除字段的方式修改文档的结构。文档在一个集合内不需要有相同的字段集。

在实际使用中,一般一个集合内的数据多半会有相同或者类似的结构。但是这个不是一个必要的条件。MongoDB灵活的数据模式意味着模式转换和修改非常简单。你很少需要写个脚本来执行 “alter table”类型的DDL操作。这一点对于敏捷式开发有非常好的帮助。

我可以用什么编程语言来喝MongoDB交互?

MongoDB支持几乎所有常用的编程语言。参见:ecosystem:latest list of drivers </drivers>

MongoDB支持SQL吗?

不支持。

但是,MongoDB自带一种丰富的动态查询语言。

参见

Operators

典型的MongoDB应用是什么?

MongoDB的定位是一种通用型数据库,它可以使用在很多应用场景下面。如内容管理,移动应用,游戏,电商,分析,存档和日志等等

MongoDB不适合那些需要使用SQL,关联和多文档事务的应用。

MongoDB支持ACID事务吗?

MongoDB不支持多文档事务。

然而,MongoDB对单文档支持原子性操作。往往这种文档级的原子性操作可以满足很多在关系型数据库中需要事务的应用场景。

举例来说,你可以把相关数据内嵌在一个文档的数组字段或者嵌套文档内,对这些数据的更新可以在一个原子操作内完成。在关系型数据库中同样的数据可能分布在不同的表和列内,在那样的情况下需要强事务支持来保证那些数据更新的原子性。

MongoDB允许客户端读取落盘之前文档的修改,不管你的写安全机制和恢复日志设置如何。正因如此,应用程序可能会观察到两种不同的行为:

  • 对那些有多个同时读写操作的应用,MongoDB会允许客户端读取一个写操作的结果,哪怕那个写操作还没返回。

  • 加入 mongod 在日志落盘前异常终止,哪怕写操作已经正常完成,一个查询可能会读到一些数据,而那些数据在mongod重启之后将不存在。

在其他数据库里这就是所谓的 脏读

在你使用了*journaled write concern* 的时候,如果 mongod 成功确认写操作 那么数据就已经完全落盘,在mongod重新启动时候会保证数据的存在。

对于复制集来说,一个写操作只有在复制集多数成员上写到日志才意味着真正的持久。 无论是否在安全写级别里面指定写日志(Journaled write),MongoDB会自动定时把日志进行刷盘。这个时间间隔可以有mongod的启动参数 commitIntervalMs 来指定。

MongoDB需要很多内存么?

不一定。MongoDB可以在一个内存较小的机器上运行。

MongoDB 会使用系统所有可用内存作为它的缓存。 系统监控会显示MongoDB使用很多内存,但是这些内存的使用是动态的。如果另外一个进程突然需要服务器一半的内存,MongoDB会把内存让给其他进程。

从技术上来说,操作系统的虚拟内存管理模块负责管理MongoDB的内存使用。这意味着MongoDB可以用到系统所有的可用内存,并在必要的时候会使用交换内存。部署的时候尽量要使用足够的内存来装下工作集数据(热数据)。

参见

FAQ: MongoDB Diagnostics 更多关于MongoDB内存使用的问题。

我如何配置缓存大小

MongoDB 不支持配置缓存。MongoDB会通过内存映射的技术使用所有可用内存。这一点和操作系统处理文件系统缓存原理是一致的。

在MongoDB里面是否需要为应用程序缓存单独加一个缓存层?

不需要。在MongoDB里面,一个文档的结构和其在应用程序内存里的结构是相似的。这意味着数据库里存储的已经是一种可以直接使用的格式。这样在应用程序端就不再需要一个单独的缓冲层。

这点和关系型数据库不一样。关系型数据库缓存比较昂贵,它必须首先把数据转换成对象模式然后保存在一个单独的缓存器。如果从数据转换成对象的时候需要关联,那么这个过程就会有很多额外开销。

MongoDB支持缓存吗?

是的。MongoDB会把最近所用的数据保持在内存里。如果你的索引数据和你的工作集数据小于内存的大小,那么MongoDB就可以从内存里直接处理你的查询。

MongoDB 没有查询缓存。MongoDB会直接从索引和数据文件里读取数据来处理查询请求。

所有的写操作是立即刷盘还是滞后的?

默认情况下,所有写操作会在100ms之内写入到日志文件 journal 在这个时候写操作就是持久的了 - 假如你这个时候把电源拔掉,机器重启后数据还是会在的。 参见 commitIntervalMs 来了解更多关于日志落盘间隔的信息。

虽然日志落盘几乎是实时的,但是MongoDB的数据落盘是异步的。MongoDB有可能会等到60秒才把数据写入数据文件。这个不影响数据持久性,因为日志里面有足够的信息用来做宕机时候的恢复动作。数据落盘间隔可以通过 syncPeriodSecs 设置来调整

MongoDB使用什么变成语言写的?

MongoDB是用C++写的。驱动程序和客户端一般会用各自的语言编写。有一些驱动程序用一些C模块来提高性能。

MongoDB 32位的限制是什么?

MongoDB使用 memory-mapped files 技术。如果使用32位版本,那么总共的存储空间,包括数据和索引,是2个G。正因为这个原因,请不要在生产环境部署32位机。

假如你使用的是64位版本,那基本上对存储没有限制。我们强烈建议在生产环境中使用64位版本。

注解

32位系统默认禁止日志(journaling) 因为日志会进一步减小数据库可存储空间的容量。