民工哥 MongoDB 教程:知识体系与基础概念
MongoDB 知识体系介绍

MongoDB 生态介绍

什么是 NoSQL?
NoSQL是一种非关系型DMS,不需要固定的架构,可以避免joins链接,并且易于扩展。NoSQL数据库用于具有庞大数据存储需求的分布式数据存储。NoSQL用于大数据和实时Web应用程序。例如,像Twitter,Facebook,Google这样的大型公司,每天可能产生TB级的用户数据。
NoSQL数据库代表“不仅仅是SQL”或“不是SQL”。虽然NoRELNoSQL会是一个更好的名词。Carl Strozz在1998年引入了NoSQL概念。
传统的RDBMS使用SQL语法来存储和查询数据。相反,NoSQL数据库系统包含可存储结构化,半结构化,非结构化和多态数据的多种数据库技术。
为什么使用 NoSQL?
NoSQL 数据库的概念在处理大量数据的互联网巨头(例如Google,Facebook,Amazon等)中变得很流行。使用RDBMS处理海量数据时,系统响应时间变慢。
为了解决此问题,当然可以通过升级现有硬件来“横向扩展”我们的系统。但这个成本很高。
这个问题的替代方案是在负载增加时将数据库负载分配到多个主机上。这种方法称为“横向扩展”。NoSQL数据库是非关系数据库,因此在设计时考虑到Web应用程序,比关系数据库更好地扩展。
NoSQL数据库的简要历史
-
1998年-Carlo Strozzi在他的轻量级开源关系数据库中使用术语NoSQL -
2000-图形数据库Neo4j启动 -
2004年-推出Google BigTable -
2005年-启动CouchDB -
2007年-发布有关Amazon Dynamo的研究论文 -
2008年-Facebook开源Cassandra项目 -
2009年-重新引入NoSQL术语
NoSQL的功能
非关系
-
NoSQL数据库从不遵循关系模型 -
切勿为tables 提供固定的固定列记录 -
使用自包含的聚合或BLOB -
不需要对象关系映射和数据规范化 -
没有复杂的功能,例如查询语言,查询计划者, -
参照完整性联接,ACID
动态架构
-
NoSQL数据库是无模式的或具有宽松模式的数据库 -
不需要对数据架构进行任何形式的定义 -
提供同一域中的异构数据结构

简单的API
-
提供易于使用的界面,用于存储和查询提供的数据 -
API允许进行低级数据操作和选择方法 -
基于文本的协议,通常与带有JSON的HTTP REST一起使用 -
多数不使用基于标准的查询语言 -
支持Web的数据库作为面向互联网的服务运行
分布式
-
可以以分布式方式执行多个NoSQL数据库 -
提供自动缩放和故障转移功能 -
通常可牺牲ACID概念来实现可伸缩性和吞吐量 -
分布式节点之间几乎没有同步复制,多为异步多主复制,对等,HDFS复制 -
仅提供最终的一致性 -
无共享架构。这样可以减少协调并提高分布。

MongoDB 基础概念
什么是MongoDB
MongoDB是面向文档的NoSQL数据库,用于大量数据存储。MongoDB是一个在2000年代中期问世的数据库。属于NoSQL数据库的类别。
MongoDB功能
每个数据库都包含集合,而集合又包含文档。每个文档可以具有不同数量的字段。每个文档的大小和内容可以互不相同。文档结构更符合开发人员如何使用各自的编程语言构造其类和对象。开发人员经常会说他们的类不是行和列,而是具有键值对的清晰结构。从NoSQL数据库的简介中可以看出,行(或在MongoDB中调用的文档)不需要预先定义架构。相反,可以动态创建字段。MongoDB中可用的数据模型使我们可以更轻松地表示层次结构关系,存储数组和其他更复杂的结构。可伸缩性– MongoDB环境具有很高的可伸缩性。全球各地的公司已经定义了自己的集群,其中一些集群运行着100多个节点,数据库中包含大约数百万个文档。
为什么使用MongoDB
以下是一些为什么应该开始使用MongoDB的原因
-
面向文档的–由于MongoDB是NoSQL类型的数据库,它不是以关系类型的格式存储数据,而是将数据存储在文档中。这使得MongoDB非常灵活,可以适应实际的业务环境和需求。 -
临时查询-MongoDB支持按字段,范围查询和正则表达式搜索。可以查询返回文档中的特定字段。 -
索引-可以创建索引以提高MongoDB中的搜索性能。MongoDB文档中的任何字段都可以建立索引。 -
复制-MongoDB可以提供副本集的高可用性。副本集由两个或多个mongo数据库实例组成。每个副本集成员可以随时充当主副本或辅助副本的角色。主副本是与客户端交互并执行所有读/写操作的主服务器。辅助副本使用内置复制维护主数据的副本。当主副本发生故障时,副本集将自动切换到辅助副本,然后它将成为主服务器。 -
负载平衡-MongoDB使用分片的概念,通过在多个MongoDB实例之间拆分数据来水平扩展。MongoDB可以在多台服务器上运行,以平衡负载或复制数据,以便在硬件出现故障时保持系统正常运行。
MongoDB常用术语
下面是MongoDB中使用的一些常用术语
-
_id – 这是每个MongoDB文档中必填的字段。_id字段表示MongoDB文档中的唯一值。_id字段类似于文档的主键。如果创建的新文档中没有_id字段,MongoDB将自动创建该字段。 -
集合 – 这是MongoDB文档的分组。集合等效于在任何其他RDMS(例如Oracle或MS SQL)中创建的表。集合存在于单个数据库中。从介绍中可以看出,集合不强制执行任何结构。 -
游标 – 这是指向查询结果集的指针。客户可以遍历游标以检索结果。 -
数据库 – 这是像RDMS中那样的集合容器,其中是表的容器。每个数据库在文件系统上都有其自己的文件集。MongoDB服务器可以存储多个数据库。 -
文档 - MongoDB集合中的记录基本上称为文档。文档包含字段名称和值。 -
字段 - 文档中的名称/值对。一个文档具有零个或多个字段。字段类似于关系数据库中的列。
下图显示了带有键值对的字段的示例。如下的例子中,CustomerID和11是文档中定义的键值对之一。
MongoDB与RDBMS区别
下表将帮助您更容易理解Mongo中的一些概念:
MongoDB 体系结构
MongoDB包组件结构
主要是MongoDB数据库服务以及一些工具。
MongoDB Database Tools
-
二进制导入导出 -
mongodump
-
mongorestore
-
bsondump
-
-
数据导入导出 -
mongoimport
-
mongoexport
-
-
诊断工具 -
mongostat
-
mongotop
-
-
GridFS 工具 -
mongofiles
-
除了上述没有列举到,还有:
-
mongoperf
: mongoDB自带工具,用于评估磁盘随机IO性能。
包组件可以在官网MongoDB Package Components找到详细的用法。
其中最主要的程序当然是mongod(数据库服务),mongod在不同的部署方案中(单机部署,副本集部署,分片集群部署),通过不同的配置,可以扮演多种不同的角色:
-
在单机部署中扮演 数据库服务器(提供所有读写功能) -
在副本集部署中,通过配置,可以部署为 primary节点(主服务器,负责写数据,也可以提供查询)、secondary节点(从服务器,它从主节点复制数据,也可以提供查询)、以及arbiter节点(仲裁节点,不保存数据,主要用于参与选举投票) -
在分片集群中,除了在每个分片中扮演上述角色外,还扮演着配置服务器的角色(存储有分片集群的所有元数据信息,mongos的数据路由分发等都要依赖于它)
在一台服务器上,可以启动多个mongod服务。但在实际生产部署中,通常还是建议一台服务器部署一个mongod实例,这样不仅减少资源竞争,而且服务器故障也不会同时影响到多个服务。
MongoDB数据逻辑结构
MongoDB 数据逻辑结构分为数据库(database)、集合(collection)、文档(document)三层 :
-
一个mongod实例中允许创建多个数据库。 -
一个数据库中允许创建多个集合(集合相当于关系型数据库的表)。 -
一个集合则是由若干个文档构成(文档相当于关系型数据库的行,是MongoDB中数据的基本单元)。
数据库
一个数据库中可以创建多个集合,原则上我们通常把逻辑相近的集合都放在一个数据库中,当然出于性能或者数据量的关系,也可能进行拆分。
在MongoDB中有几个内建的数据库:
-
admin admin库主要存放有数据库帐号相关信息。 -
local local数据库永远不会被复制到从节点,可以用来存储限于本地单台服务器的任意集合副本集的配置信息、oplog就存储在local库中。 -
重要的数据不要存储在local库,因为没有冗余副本,如果这个节点故障,存储在local库的数据就无法正常使用了。
-
-
config config数据库用于分片集群环境,存放了分片相关的元数据信息。 -
test MongoDB默认创建的一个测试库,连接mongod服务时,如果不指定连接的具体数据库,默认就会连接到test库。
集合
集合由若干条文档记录构成。
-
前面介绍MongoDB的时候提到过,集合是schema-less的(无模式或动态模式),这意味着集合不需要在读写数据前创建模式就可以使用,集合中的文档也可以拥有不同的字段,随时可以任意增减某个文档的字段。 -
在集合上可以对文档进行增删改查以及进行聚合操作。 -
在集合上还可以对文档中的字段创建索引。 -
除了一般的集合外,还可以创建一种叫做定容集合(capped collection)类型的集合,这种集合与一般集合主要的区别是,它可以限制集合的容量大小,在数据写满的时候,又可以从头开始覆盖最开始的文档进行循环写入。 -
副本集就是利用这种类型的集合作为oplog,记录primary节点上的写操作,并且同步到从节点重放,以实现主副节点数据复制的功能。
文档
文档是MongoDB中数据的基本存储单元,它以一种叫做BSON文档的结构表示。BSON,即Binary JSON,多个键及其关联的值有序地存放在其中,类似映射,散列或字典。
-
文档中的键/值对是有序的,不同序则是不同文档。并且键是区分大小写的,否则也为不同文档。 -
文档的键是字符串,而值除了字符串,还可以是int, long, double,boolean,子文档,数组等多种类型。 -
文档中不能有重复的键。 -
每个文档都有一个默认的_id键,它相当于关系型数据库中的主键,这个键的值在同一个集合中必须是唯一的,**_id键值默认是ObjectId类型**,在插入文档的时候,如果用户不设置文档的_id值得话,MongoDB会自动生成生成一个唯一的ObjectId值进行填充。
MongoDB数据库文件
注意
MongoDB数据库文件和MongoDB存储的引擎有直接关系,MongoDB一共提供了三种存储引擎:WiredTiger,MMAPV1和In Memory;在MongoDB3.2之前采用的是MMAPV1; 后续版本v3.2开始默认采用WiredTiger;且在v4.2版本中移除了MMAPV1的引擎。
在后续文章中,还将对MongoDB存储引擎进行详解。
MongoDB - MMAPv1引擎下的数据库文件
由于v3.0后续版本已经弃用了,所以这里不会详细介绍。
-
journal 日志文件 -
namespace 表名文件 -
data 数据及索引文件
db
|------journal
|----_j.0
|----_j.1
|----lsn
|------local
|----local.ns
|----local.0
|----local.1
|------mydb
|----mydb.ns
|----mydb.0
|----mydb.1
如果你希望详解了解MongoDB MMAP的引擎(源码级别),你可以参考这篇MongoDB Mmap 引擎分析(https://cloud.tencent.com/developer/article/1004385)
MongoDB - WiredTiger
MongoDB v3.2已经将WiredTiger设置为了默认的存储引擎
-
collection-*.wt
存储collection的数据 -
index-*.wt
存储索引的数据 -
WiredTiger
存储基本配置信息 -
WiredTiger.wt
存储所有其它collection的元数据信息 -
WiredTiger.lock
存储进程ID,用于防止多个进程连接同一个Wiredtiger数据库 -
WiredTiger.turtle
存储WiredTiger.wt的元数据信息 -
journal
存储Write ahead log
后续的文章将对WiredTiger存储引擎进行详解。