常见问题解答:MongoDB 基础知识

在本页面

本文档回答了有关 MongoDB 的一些常见问题。

MongoDB 支持哪些平台?

有关受支持平台的列表,请参见Supported Platforms

MongoDB 是否作为托管服务提供?

是。 MongoDB Atlas是一种云托管的数据库即服务。有关更多信息,请访问MongoDB Atlas 文档

集合与表格有何不同?

MongoDB 数据库将其数据存储在collections中,而不是表。集合包含一个或多个BSON documents。文档类似于关系数据库表中的记录或行。每个文档都有一个或多个字段;字段类似于关系数据库表中的列。

如何创建数据库和集合?

如果数据库不存在,则当您第一次为该数据库存储数据时,MongoDB 会创建该数据库。

如果不存在集合,则在您第一次为该集合存储数据时,MongoDB 会创建该集合。 [1]

这样,您可以切换到不存在的数据库(use <dbname>)并执行以下操作:

use myNewDB

db.myNewCollection1.insertOne( { x: 1 } )
db.myNewCollection2.createIndex( { a: 1 } )

insert操作同时创建数据库myNewDB和集合myNewCollection1(如果它们尚不存在)。

创建myNewDB之后发生的createIndex操作将创建索引和集合myNewCollection2(如果该集合不存在)。如果myNewDb不存在,则createIndex操作也会创建myNewDB

[1] 如果要指定特定选项(例如最大尺寸或文档验证规则),也可以使用db.createCollection显式创建一个集合。

如何定义或更改收集模式?

您无需在 MongoDB 中为集合指定架构。尽管集合中的文档通常具有很大程度上相同的结构,但这不是必需的;即单个集合中的文档不需要具有相同的字段集。字段的数据类型在集合中的文档之间也可能不同。

要更改集合中文档的结构,请将文档更新为新结构。例如,添加新字段,删除现有字段或将字段值更新为新类型。

在版本 3.2 中进行了更改:从 MongoDB 3.2 开始,但是,您可以在更新和插入操作期间对集合强制执行文件验证规则

可以在显式创建集合时指定某些集合属性,例如指定最大大小,然后对其进行修改。参见db.createCollectioncollMod。如果未指定这些属性,则无需显式创建集合,因为在首次存储集合数据时,MongoDB 会创建新集合。

MongoDB 是否支持 SQL?

不直接,不。但是,MongoDB 确实支持自己的丰富查询语言。有关使用 MongoDB 查询语言的示例,请参见MongoDB CRUD 操作

您也可以使用适用于 BI 的 MongoDB 连接器通过 SQL 查询 MongoDB 集合。

MongoDB 是否支持事务?

因为单个文档可以包含相关数据,否则它们将在关系模式中的各个父子表之间建模,因此 MongoDB 的原子单文档操作已经提供了满足大多数应用程序数据完整性需求的事务语义。一个或多个字段可以在单个操作中编写,包括对多个子文档和数组元素的更新。 MongoDB 提供的保证可确保在文档更新时完全隔离。任何错误都会导致操作回滚,以便 Client 端获得文档的一致视图。

从版本 4.0 开始,对于需要原子性来更新多个文档或读取多个文档之间保持一致性的情况,MongoDB 为副本集提供multi-document transactions,而分片群集的事务则计划在 MongoDB 4.2 中进行。

Important

在大多数情况下,与单文档写入相比,多文档事务产生的性能成本更高,并且多文档事务的可用性不应替代有效的架构设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)将 continue 是您的数据和用例的最佳选择。也就是说,在许多情况下,适当地对数据建模将最大程度地减少对多文档 Transaction 的需求。

Note

我们为产品描述的任何功能的开发,发布和时间安排均由我们自行决定。此信息仅用于概述我们的总体产品方向,在做出购买决策时不应以该信息为依据,也不是提供任何材料,代码或功能的承诺,承诺或法律义务。

MongoDB 是否处理缓存?

是。 MongoDB 将最近使用的数据保留在 RAM 中。如果您为查询创建了索引,并且您的工作数据集适合 RAM,那么 MongoDB 将从内存中提供所有查询。

MongoDB 不会缓存查询结果以返回相同查询的缓存结果。

有关 MongoDB 和内存使用的更多信息,请参阅WiredTiger 和内存使用MMAPv1 和内存使用

MongoDB 如何解决 SQL 或查询注入?

BSON

Client 端程序在 MongoDB 中组装查询时,将构建 BSON 对象而不是字符串。因此,传统的 SQL 注入攻击不是问题。更多细节和一些细微差别将在下面介绍。

MongoDB 将查询表示为BSON个对象。通常client libraries提供了一个方便的,无注入的过程来构建这些对象。考虑下面的 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

Note

您可以通过在命令行中传递--noscripting选项或在配置文件中设置security.javascriptEnabled来禁用所有服务器端 JavaScript 的执行。

以下所有 MongoDB 操作均允许您直接在服务器上运行任意 JavaScript 表达式:

在这些情况下,您必须格外小心,以防止用户提交恶意 JavaScript。

幸运的是,您可以在不使用 JavaScript 的 MongoDB 中表达大多数查询,对于需要 JavaScript 的查询,您可以在单个查询中混合使用 JavaScript 和非 JavaScript。将所有用户提供的字段直接放在BSON字段中,然后将 JavaScript 代码传递给$where字段。

如果需要在$where子句中传递用户提供的值,则可以使用CodeWScope机制对这些值进行转义。在范围文档中将用户提交的值设置为变量时,可以避免在数据库服务器上评估它们。

首页