MongoDB中的基础概念:Databases、Collections、Documents

401 阅读5分钟

MongoDB以BSON格式的文档(Documents)形式存储。Databases中包含集合(Collections),集合(Collections)中存储文档(Documents)。

BSON是一个二进制形式的JSON文档,它比JSON包含更多的数据类型。对于BSON规格,可参见bsonspec.org,也可参考BSON类型

Databases

在MongoDB中,databases保存文档(Documents)的集合(Collections)。

在Mongo Shell中,通过使用use <db>命令来选中database,就像下面的例子:

| ``` use myDB

| ----------------- |

#### 创建Database

如果database不存在,MongoDB会在第一次为database存储数据的时候创建。因此,你可以直接切换到一个不存在的数据库,然后执行下面的语句:

| ```
use myNewDB  db.myNewCollection1.insert( { x: 1 } ) 
``` |
| ------------------------------------------------------------ |

`insert()`操作会创建名为myNewDB的database和名为myNewCollection1的collection(如果他们不存在的话)。

## Collections

MongoDB在collections中存储文档(documents)。Collections类似于关系型数据库中的表(tables)。

#### 创建Collection

如果collection不存在,MongoDB会在第一次为collection存储数据的时候创建。

| ```
db.myNewCollection2.insert( { x: 1 } ) db.myNewCollection3.createIndex( { y: 1 } ) 
``` |
| ------------------------------------------------------------------------------------------- |

无论是insert()还是createIndex()操作,都会创建它们各自指定的收集,如果他们不存在的话。

#### 显式创建

MongoDB提供db.createCollection()方法来显式创建一个collection,同时还能设置各种选项,例如:设置最大尺寸和文档校验规则。如果你没有指定这些选项,那么你就不需要显式创建collection,因为MongoDB会在你创建第一个数据的时候自动创建collection。

若要修改这些collection选择,可查看[collMod](https://docs.mongodb.com/manual/reference/command/collMod/#dbcmd.collMod)。

#### Documents校验

3.2.x版本新增内容。

默认情况下,collection不要求文档有相同的结构;例如,在一个collection的文档不必具有相同的fields,对于单个field在一个collection中的不同文档中可以是不同的数据类型。

从MongoDB 3.2开始,你可以在对collection进行update和insert操作的时候执行文档(documents)校验规则。具体可参见[文档验证的详细信息](https://docs.mongodb.com/manual/core/document-validation/)。

## Documents

#### Document结构

MongoDB的文件是由field和value对的结构组成,例如下面这样的结构:

| ```
{    field1: value1,    field2: value2,    field3: value3,    ...    fieldN: valueN } 
``` |
| ---------------------------------------------------------------------------------------------- |

value值可以是任何BSON数据类型,包括:其他document,数字,和document数组。

例如下面的document,包含各种不同类型的值:

| ```
var mydoc = {     _id: ObjectId("5099803df3f4948bd2f98391"),     name: {          first: "Alan", last: "Turing"      },     birth: new Date('Jun 23, 1912'),     death: new Date('Jun 07, 1954'),     contribs: [ "Turing machine", "Turing test", "Turingery" ],     views : NumberLong(1250000) } 
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

上面例子中的各fields有下列数据类型:

-   _id:[ObjectId](https://docs.mongodb.com/manual/reference/bson-types/#objectid)类型
-   name:一个嵌入的document,包含first和last字段
-   birth和death:Date类型
-   contribs:字符串数组
-   views:NumberLong类型

#### Field名

Field名是一个字符串。

Documents中的filed名有下列限制:

-   _id被保留用于主键;其值必须是集合中唯一的、不可变的、并且可以是数组以外的任何数据类型
-   不能以美元符号`$`开头
-   不能包含点字符`.`
-   不能包含空字符

#### Field Value限制

对于索引的collections,索引字段中的值有最大长度限制。详情请参见[Maximum Index Key Length](https://docs.mongodb.com/manual/reference/limits/#Index-Key-Limit)。

#### 圆点符号

MongoDB中使用圆点符号`.`访问数组中的元素,也可以访问嵌入式Documents的fields。

###### Arrays数组

通过圆点符号`.`来链接Arrays数组名字和从0开始的数字位置,来定位和访问一个元素数组:

| ```
"<array>.<index>" 
``` |
| -------------------------- |

举例:对于下面的document:

| ```
{    ...    contribs: [ "Turing machine", "Turing test", "Turingery" ],    ... } 
``` |
| ----------------------------------------------------------------------------------------- |

要访问contribs数组中的第三个元素,可以这样访问:

| ```
"contribs.2" 
``` |
| --------------------- |

###### 嵌入式Documents

通过圆点符号`.`来链接嵌入式document的名字和field名,来定位和访问嵌入式document:

| ```
"<embedded document>.<field>" 
``` |
| -------------------------------------- |

举例:对于下面的document:

| ```
{    ...    name: { first: "Alan", last: "Turing" },    ... } 
``` |
| ---------------------------------------------------------------------- |

要访问name中的last字段,可以这样使用:

| ```
"name.last" 
``` |
| -------------------- |

#### Documents限制

Documents有下面这些属性和限制:

###### Document大小限制

每个BSON文档的最大尺寸为16兆字节。

最大文档大小有助于确保一个单个文档不会使用过量的内存,或通信过程中过大的带宽占用。

若要存储超过最大尺寸的文档,MongoDB提供了GridFS API。可以看[mongofiles](https://docs.mongodb.com/manual/reference/program/mongofiles/#bin.mongofiles)和更多有关GridFS的[文档](https://docs.mongodb.com/manual/applications/drivers/)

###### Document Field顺序

MongoDB中field的顺序默认是按照写操作的顺序来保存的,除了下面几种情况:

-   _id总是document的第一个field
-   可能会导致文档中的字段的重新排序的更新,包括字段名重命名。

在2.6版本起,MongoDB开始积极地尝试保留document中field的顺序。

###### _id字段

_id字段有以下行为和限制:

-   默认情况下,MongoDB会在创建collection时创建一个_id字段的唯一索引
-   _id字段总是documents中的第一个字段。如果服务器接收到一个docuement,它的第一个字段不是_id,那么服务器会将_id字段移在开头
-   _id字段可以是除了array数组之外的任何BSON数据格式

以下是存储_id值的常用选项:

-   使用[ObjectId](https://docs.mongodb.com/manual/reference/bson-types/#objectid)
-   最好使用自然的唯一标识符,可以节省空间并避免额外的索引
-   生成一个自动递增的数字。请参阅[创建一个自动递增序列字段](https://docs.mongodb.com/manual/tutorial/create-an-auto-incrementing-field/)
-   在您的应用程序代码中生成UUID。为了更高效的在collection和_id索引中存储UUID值,可以用BSON的BinData类型存储UUID。

**大部分MongoDB驱动客户端会包含_id字段,并且在发送insert操作的时候生成一个ObjectId。但是如果客户端发送一个不带_id字段的document,mongod会添加_id字段并产生一个ObjectId**