常见问题:MongoDB基础知识

Posted MongoDB中文用户组

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常见问题:MongoDB基础知识相关的知识,希望对你有一定的参考价值。

· MongoDB支持哪些平台?

· MongoDB作为托管服务提供吗?

· 集合(collection)与表(table)有何不同?

· 如何创建数据库(database)和集合(collection)?

· 如何定义或修改集合模式(schema)?

· MongoDB是否支持SQL?

· MongoDB是否支持事务?

· MongoDB是否处理缓存?

· MongoDB如何解决SQL或Query注入问题?


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


MongoDB支持哪些平台?

有关支持的平台列表,请参阅 支持的平台。


MongoDB作为托管服务提供吗?

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


集合(collection)与表(table)

有何不同?

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


也可以看看:

SQL到MongoDB映射图, MongoDB简介


如何创建数据库(database)和集合(collection)?

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

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

 

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

use myNewDB

db.myNewCollection1.insertOne( { x: 1 } )

db.myNewCollection2.createIndex( { a: 1 } )

 

如果数据库myNewDB和集合myNewCollection1尚不存在,insert操作将创建它们。

 

发生在myNewDB库创建之后的createIndex操作,将创建索引,并且如果集合不存在的话同时也会创建myNewCollection2集合。如果myNewDb库不存在的话,createIndex操作也将创建myNewDB数据库。

 

[1] 如果要指定特定的集合选项,你也可以明确的使用db.createCollection来创建一个集合,例如指定最大大小或文档验证规则。


如何定义或修改集合模式(schema)?

在MongoDB中您不需要为集合指定模式。虽然集合中的文档通常具有基本上同质的结构,但这不是必需的; 即,单个集合中的文档不需要具有一组相同的字段。字段的数据类型也可以在集合中的文档之间存在不同。

 

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

 

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

 

某些集合属性(例如指定最大大小)可以在显式创建集合期间指定并进行修改。见db.createCollection和collMod。如果未指定这些属性,则无需显式创建集合,因为MongoDB在首次存储集合数据时会创建新集合。


MongoDB是否支持SQL?

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

 

您还可以使用MongoDB Connector for BI来使用SQL查询MongoDB集合。

 

也可以看看:

SQL到MongoDB映射图表


MongoDB是否支持事务?

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

 

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

 

重要:

在大多数情况下,多文档事务比单个文档写入产生更高的性能成本,并且多文档事务的可用性不应该取代高效的模式设计。对于许多场景, 非范式数据模型(嵌入式文档和数组)将继续为您的数据和用例提供最佳选择。也就是说,对于许多场景,适当地对数据建模将最大限度地减少对多文档事务的需求。

 

[2] 我们产品所描述的任何特性或功能的开发,发布和时间由我们自行决定。此信息仅用于概述我们的一般产品方向,不应依赖这些做出购买决定,也不是承诺,保证或法律义务的提供任何材料,代码或功能。


MongoDB是否处理缓存?

是。MongoDB将最近使用的数据保存在内存中。如果您为查询创建了索引,并且您的工作数据集适合内存大小,则MongoDB将从内存中进行查询。

 

MongoDB不会缓存查询结果,以便为相同查询返回缓存结果。

 

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


MongoDB如何解决

SQL或Query注入问题?

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"}。如果包含特殊字符,例如 ,:和{,查询根本不会匹配上任何文档。例如,用户无法劫持查询并将其转换为删除。

javascript

注意:

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

 

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

·$where

·mapReduce

·group

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

 

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

 

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


分类:常见问题, 基础知识

标签:常见问题, FAQ, 基础知识, SQL注入, 模式, schema, 事务, 缓存

译者


钟秋

BBD技术经理,资深架构师,MongoDB中文社区联席主席

有丰富项目中应用MongoDB经验,熟悉MongoDB相互模式设计及性能优化,熟悉大数据相关技术和互联网及大数据应用架构设计



以上是关于常见问题:MongoDB基础知识的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB数据库系列MongoDB基础

MongoDB基础学习 MongoDB概念解析

兄弟连学python---MongoDB基础知识

MongoDB01MongoDB基础

MongoDB基础之MongoDB安装

MongoDB基础