MongoDB系列(一)MongoDB简介

MongoDB是一款强大、灵活、易于扩展的、由C++编写的聚合型、文档型、NoSQL数据库,支持二级索引、范围查询、排序、聚合、地理空间索引等功能。

MongoDB是面向文档的数据库,不是关系型数据库,不采用关系模型是为了更好的扩展性。与关系型数据库相比,有以下特点:

  • 没有“一行数据”的概念,取而代之的是“一条文档”
  • 不再有预定义模式,文档的键和值不再是固定的类型和大小,可以随意扩展。
  • 易于扩展,随着数据的增长,横向扩展(增加机器)变得更加方便,MongoDB能够自动处理跨集群的数据和负载,自动重新分配文档、自动将用户请求路由至正确的机器上。
  • 功能丰富,支持索引、聚合、文件存储、以及特殊集合,如会过期的数据:日志、会话等。
  • 性能更强,4.0版本前不支持事务,但提供了诸多原子操作:文档的保存、修改、删除。

img

文档与集合

文档是MongoDB中数据的基本单元,类似于关系型数据库管理系统中的行,但灵活性更高。例如:

{"name":"xiaoming","age":20}

集合是一组文档,可以看做是一个拥有动态模式的表。因此,MongoDB中的文档没有预定义模,一个集合中可以保存多个完全不同的文档,例如:

1
2
3
1  {"name":"xiaoming", "age":20}
2 {"name":"xiaohei", "age":20, "man":true, "address":"sz"}
3 {"device":"rcu","devId":"1234567890"}

备注:集合命名时,不能有空字符串、不能包含\0、不能包含$、不能以system.开头

数据库

多个集合组成一个数据库、一个MongoDB实例包含多个数据库,每个数据库拥有独立的权限,在磁盘上,不同的数据库放置在不同的文件夹中,一般的,一个应用程序使用一个数据库。

有三个数据库是默认保留的:admin(root库)、local(用于副本集模式)、config(用于分片模式)

数据类型

MongoDB的文档与JavaScript中对象相近,类似于JSON,MongoDB支持JSON包含的6种数据类型:null、布尔型、数值、字符串、数组、对象,MongoDB还添加了其他一些数据类型:日期、正则表达式、数组、内嵌文档、对象id、二进制数据、JavaScript代码。

下面只介绍:日期、数组、内嵌文档、对象id。

日期

对应JAVA、JS中的Date类,存入数据库的是Date对象,不是日期字符串。数据库中存储的日期为新纪元以来的毫秒数,并未存储时区,Date对象与毫秒之间的转换,由MongoDB负责,客户端不需要关心。

数组

与JAVA数组不同的是,数组可以包含不同类型的元素,数组可以嵌套数组。

1
{"things":["apple", 3.1415926]}

内嵌文档

文档可以作为键的值,这样的文档就是内嵌文档。类似于JSON嵌套。

1
2
3
4
5
6
{
"things":{
"name":"apple"
"price":3.14
}
}

objectId

MongoDB存储的文档必需有一个”_id“键,这个键可以是任意类型,默认是个ObjectId对象。objectId作为文档的唯一标识符。如果插入文档时,没有设置objectId,MongoDB客户端驱动会自动创建一个。

object_id大小为12字节,是一个由24个十六进制数字组成的字符串。

1566887583799

  • 时间戳:占用前4个字节,从标准纪元开始的时间戳,单位为秒,

  • 机器标识位:占用3个字节,是所在主机名的唯一标识,通常是机器名的hash值。

  • PID:产生 objectId的进程的ID

  • 计数器: 前9个字节保证了同一秒钟不同机器不同进程的ObjectId是唯一的,最后三个字节用来确保同一秒同机器同进程的objectId的唯一性。所以每个进程同一秒最多允许产生
    $$
    (2^8)^3=16777216
    $$
    个不同的objectId。对于服务器来说,1600W个足够用了。

从objectId的设计可以看出,MongoDB的设计初衷就是用作分布式数据库,能够在副本集、分片环境下生成全局唯一id。