FAQ: MongoDB Fundamentals
在此页面上
本文档回答有关 MongoDB 的一些常见问题。
MongoDB 支持哪些平台?
有关支持的平台列表,请参阅 平台支持。
MongoDB 是否作为托管服务而提供?
是。MongoDB Atlas 是一项云托管的数据库即服务。有关更多信息,请访问 MongoDB Atlas。
集合与表格有何不同?
MongoDB 数据库将其数据存储在集合中,而不是表中。一个集合包含一个或多个 BSON 文档。文档类似于关系数据库表中的记录或行。每个文档都有一个或多个字段;字段类似于关系数据库表中的列。
如何创建数据库和集合?
注意
您可以使用 MongoDB Shell
输入本常见问题解答中提及的命令。MongoDB Shell 是 MongoDB 的交互式 JavaScript 界面。您可以使用 MongoDB Shell 来查询和更新数据以及执行管理操作。
如果数据库不存在,MongoDB 会在您首次存储数据库数据时创建数据库。
如果集合不存在,MongoDB 会在您首次存储该集合的数据时创建该集合。
因此,您可以切换到一个不存在的数据库 (use <dbname>
),并执行以下操作:
use myNewDB; db.myNewCollection1.insertOne( { x: 1 } ); db.myNewCollection2.createIndex( { a: 1 } );
如果集合
myNewCollection1
尚不存在,则db.collection.insertOne()
方法将创建该集合。db.collection.createIndex()
方法可创建索引和集合myNewCollection2
(如果尚不存在)。如果
myNewDb
数据库不存在,则db.collection.createIndex()
方法或db.collection.insertOne()
方法会自动创建myNewDb
数据库。
如果要指定特定选项(如最大大小或文档验证规则),还可以使用 db.createCollection()
方法显示创建集合:
use myNewDB; db.createCollection("myNewCollection1");
如何定义或更改集合模式?
您不需要为 MongoDB 中的集合指定模式。集合中的文档通常具有较为同质的结构,但这并非必须。也就是说,同个集合中的文档不需要具有相同的字段集。对于集合中不同文档内的相同字段,它们的数据类型也可以不同。
要更改集合中文档的结构,请对文档进行更新操作。例如,添加新字段、删除现有字段或更新字段值的类型。
注意
您可以在更新和插入操作期间对集合执行文档验证规则。
某些集合属性(如指定最大大小)可以在显式创建集合时指定并修改。参见 db.createCollection()
和 collMod
。如果不指定这些属性,则无需显式创建集合,因为 MongoDB 会在您首次向集合中存储数据时创建新集合。
MongoDB 支持 SQL 吗?
并未提供直接支持。不过,MongoDB 自身支持丰富的查询语言。有关使用 MongoDB 查询语言的示例,请参阅 MongoDB 增删改查操作。
此外,也可使用适用于 BI 的 MongoDB Connector 以通过 SQL 来查询 MongoDB 集合。
如果您正在考虑将 SQL 应用程序迁移到 MongoDB,请下载《MongoDB 应用程序现代化指南》,获取最佳实践迁移指南、参考架构和其他有用资源。
MongoDB 是否支持事务?
由于单个文档可以包含相关数据(否则这些数据将在关系型模式中的不同父子表中建模),因此 MongoDB 的原子性单文档操作已经提供了充足的事务语义,能够满足大多数应用程序对数据完整性的需求。可以在单个操作中写入一个或多个字段,包括对多个子文档和数组元素进行更新。MongoDB 提供的保证可确保文档更新时实现完全隔离;任何错误都会导致操作回滚,以便客户端收到文一致的文档视图。
对于需要对多个文档(在单个或多个集合中)原子性读取和写入的情况,MongoDB 支持分布式事务,包括副本集和分片集群上的事务。
有关详细信息,请参阅事务。
重要
在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。
有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项。
MongoDB 是否处理缓存?
是的。MongoDB 将最近使用的数据保存在 RAM 中。如果您已为查询创建了索引,且您的工作数据集能加载到 RAM 中,则 MongoDB 会从内存中检索数据以响应所有查询。
MongoDB 不会为了对相同查询返回缓存数据而对查询结果进行缓存。
有关 MongoDB 和内存使用的更多信息,请参阅 WiredTiger 和内存使用。
MongoDB 如何处理 SQL 或查询注入?
BSON
当客户端程序在 MongoDB 中组装查询时,它会构建一个 BSON 对象,而不是字符串。因此,传统 SQL 注入攻击无法构成威胁。下文将介绍更多详情和部分细微差别。
MongoDB 会将查询表示为 BSON 对象。通常,客户端库提供了一个方便、无需注入的流程来构建这些对象。考虑以下 C++ 示例:
BSONObj my_query = BSON( "name" << a_name ); auto_ptr<DBClientCursor> cursor = c.query("tutorial.persons", my_query);
此处比如 my_query
的值为 { name : "Joe"
}
。如果 my_query
包含特殊字符,例如 ,
、:
和 {
,则查询根本无法匹配任何文档。例如,用户不能劫持查询,然后将其转换为删除。
JavaScript
注意
您可以禁用 JavaScript 的所有服务器端执行功能:
对于
mongod
实例,方法是在命令行中传递--noscripting
选项或在配置文件中将security.javascriptEnabled
设置为 false。对于
mongos
实例,方法是在命令行中传递--noscripting
选项或在配置文件中将security.javascriptEnabled
设置为 false。
以下 MongoDB 操作允许您直接在服务器上运行任意 JavaScript 表达式:
在这些情况下,请您务必小心谨慎,以防止用户提交恶意 JavaScript。
幸运的是,在 MongoDB 中,您无需使用 JavaScript 就能表达大多数操作。