代码改变世界

MongoDB

2018-02-08 11:08  Evan  阅读(41)  评论(0)    收藏  举报

MongoDB介绍与安装

本章主要介绍什么是MongoDB并讲解如何在Windows下安装MongoDB。

MongoDB介绍

MongoDB是集Agility(敏捷)、Scalability(可扩展性)、Performance(性能)于一身的,开源的,基于文档的非关系型数据库(即NoSQL数据库)。 
MongoDB使用C++开发,官方网站是​www.mongodb.org

MongoDB安装

MongoDB可以跑在大部分平台,如Linux、Windows、OS X,下面主要介绍Windows。

Windows安装MongoDB

下载需要的MongoDB版本,此处以MongoDB 3.0 64-bit版本为例。安装包是一个msi文件,双击安装包即可进行安装,假设指定的安装目录为E:\Program Files\MongoDB\Server\3.0,按照提示一步一步安装完成之后,我们需要对MongoDB做服务端配置。 
首先,MongoDB需要空间存放数据,我们在3.0文件夹下创建data文件夹,并在data文件夹下创建db文件夹用于存放数据。 
其次,MongoDB需要空间存放日志,我们在创建好的data文件夹下创建log文件夹用于存放数据库日志。 
接下来使用如下命令即可启动MongoDB服务端:

"E:\Program Files\MongoDB\Server\3.0\bin\mongod.exe" --dbpath "E:\Program Files\MongoDB\Server\3.0\data\db" --logpath "E:\Program Files\MongoDB\Server\3.0\data\log\mongod.log"  --directoryperdb

这样我们就可以在命令行中使用mongo localhost:27017连接MongoDB数据库,进行接下来的增删改查操作。 
相信使用过MongoDB的人都会觉得每次都要敲上边的命令启动服务端是非常痛苦的,我们可以创建MongoDB的Windows服务来简化此操作!

为MongoDB创建Windows服务

在E:\Program Files\MongoDB\Server\3.0目录下创建mongod.cfg配置文件,并写入如下配置:

dbpath=E:\Program Files\MongoDB\Server\3.0\data\db
logpath=E:\Program Files\MongoDB\Server\3.0\data\log\mongod.log

创建服务:

sc.exe create MongoDB binPath= "\"E:\Program Files\MongoDB\Server\3.0\bin\mongod.exe\" --service --config=\"E:\Program Files\MongoDB\Server\3.0\mongod.cfg\" --directoryperdb" DisplayName= "MongoDB" start= "auto"

这样,MongoDB的安装就完成了,接下来需要了解一些MongoDB的概念。

MongoDB数据库、文档、集合

mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍。

数据库

与关系型数据库一样,MongoDB存在数据库的概念,一个MongoDB可以创建多个数据库。 
我们可以使用show dbs查看所有的数据库; 
使用db显示当前数据库名称; 
使用use dbName进入dbName数据库,即使这个数据库并不存在。

C:\Users\Neal>mongo localhost:27017
MongoDB shell version: 3.0.1
connecting to: localhost:27017/test
> show dbs
local  0.078GB
> db
test
> use local
switched to db local
> 

文档

文档(document)是mongodb中的最核心的概念,是其核心单元,我们可以将文档比作关系型数据库中的记录。 
多个键及其关联的值有序的放置在一起就是文档。在mongodb中使用一种类json的bson存储数据。 
bson数据可以理解为在json的基础上添加了一些json中没有的数据类型。

以下是json与bson之间数据类型的比较:

json

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null

bson

  • String : 这是最常用的数据类型来存储数据。在MongoDB中的字符串必须是有效的UTF-8。
  • Integer : 这种类型是用来存储一个数值。整数可以是32位或64位,这取决于您的服务器。
  • Boolean : 此类型用于存储一个布尔值 (true/ false) 。
  • Double : 这种类型是用来存储浮点值。
  • Min/ Max keys : 这种类型被用来对BSON元素的最低和最高值比较。
  • Arrays : 使用此类型的数组或列表或多个值存储到一个键。
  • Timestamp : 时间戳。这可以方便记录时的文件已被修改或添加。
  • Object : 此数据类型用于嵌入式的文件。
  • Null : 这种类型是用来存储一个Null值。
  • Symbol : 此数据类型用于字符串相同,但它通常是保留给特定符号类型的语言使用。
  • Date : 此数据类型用于存储当前日期或时间的UNIX时间格式。可以指定自己的日期和时间,日期和年,月,日到创建对象。
  • Object ID : 此数据类型用于存储文档的ID。
  • Binary data : 此数据类型用于存储二进制数据。
  • Code : 此数据类型用于存储到文档中的!JavaScript代码。
  • Regular expression : 此数据类型用于存储正则表达式

下面是一个文档示例:

{ "Name" : "Neal", "Age" : 24 }

集合

集合就是文档的组合,关系型数据库中记录组成一张数据表,而在MongoDB中文档组成了集合(collection),我们可以通过show collections查看当前数据库的集合:

show collections

在mongodb中的集合是无模式的,也就是说集合中存储的文档的结构可以是不同的,比如下面的两个文档可以同时存入到一个集合中:

{ "Name" : "Neal", "Age" : 24 }
{ "Name" : "Harry", "Age" : 24 , "Gender" : "Male"}

MongDB与关系型数据库比较

以下表格准确的表现了MongoDB与关系型数据库的区别于联系:

RDBMSMongoDB
Database(数据库) Database(数据库)
Table(表) Collection(集合)
Record(记录) Document(文档)
Column(栏) Key(键)
Value(值) Value(值)

MongoDB数据的增删改查

本章主要学习MongoDB命令,在开始正题之前,我们需要做些准备工作,创建数据库和集合。 
1.使用use命令进入数据库(数据库无需创建,直接进入)

use  School

2.创建一个集合

db.createCollection("Student")

当然,我们也无需使用以上语句创建集合,直接插入一条数据也可创建集合,如:

db.Student.insert({"Name":"Neal","Age":24})

好!接下来开始正题!

增(insert)

要插入数据到 MongoDB 集合,需要使用 MongoDB 的 insert() 方法。 
insert() 命令的基本语法如下:

db.COLLECTION_NAME.insert(document)

示例:

> db.Student.insert({"Name":"Neal","Age":24})
WriteResult({ "nInserted" : 1 })

查(find)

要从MongoDB 查询集合数据,需要使用MongoDB 的 find() 方法。

db.COLLECTION_NAME.find()

示例:

> db.Student.find()
{ "_id" : ObjectId("5561c446ea24f9eb53a33536"), "Name" : "Neal", "Age" : 24 }
{ "_id" : ObjectId("5561c7e2ea24f9eb53a33537"), "Name" : "Harry", "Age" : 23, "Gender" : "Male" }

使用find()可以查询当前集合所有的文档,加入查询参数可以查询某些特定条件的数据,如查询名字是Harry的学生:

> db.Student.find({"Name":"Harry"})
{ "_id" : ObjectId("5561c7e2ea24f9eb53a33537"), "Name" : "Harry", "Age" : 23, "Gender" : "Male" }

使用findOne()可以查询第一条数据,同理加入查询参数可以查询符合特定条件的第一条数据。

ObjectId
想必大家看到查询出来的数据中添加了我们在插入过程中并没有指定的_Id字段。 
是这样的,插入文档时,如果我们不指定_id参数,MongoDB为文档分配一个独特的ObjectId。 
_id是12个字节的十六进制数,唯一标识一个集合中的每个文档。12个字节被划分如下:

_id: ObjectId(4 bytes timestamp, 3 bytes machine id, 2 bytes process id, 3 bytes incrementer)

改(Update)

MongoDB的 update() 方法用于更新文档的集合。

db.COLLECTION_NAME.update(SELECTIOIN_CRITERIA, UPDATED_DATA)

示例: 
通过下面语句可以将Name为Neal的学生Age改为20。

> db.Student.update({"Name":"Neal"},{$set:{"Age":20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.Student.find({"Name":"Neal"})
{ "_id" : ObjectId("5561c446ea24f9eb53a33536"), "Name" : "Neal", "Age" : 20 }

删(Remove)

MongoDB的 remove() 方法用于从集合中删除文档。remove() 方法接受两个参数。第一个是删除criteria(条件) ,第二是justOne标志:

  • deletion criteria :(可选)删除条件,符合条件的文件将被删除。语法:
db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)
  • justOne : (可选)如果设置为true或1,然后只删除一个文件。语法:
db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)

示例:

> db.Student.remove({"Name":"Neal"})
WriteResult({ "nRemoved" : 1 })
> db.Student.find({"Name":"Neal"})
> 

注意:使用db.Student.remove({})会删除Student集合中的所有数据,请谨慎使用。

MongoDB存储引擎

在2015/3/17以前,MongoDB只有一个存储引擎,叫做MMAP,MongoDB3.0的推出使得MongoDB有了两个引擎:MMAPv1和WiredTiger。

  • MMAPv1:适应于所有MongoDB版本,MongoDB3.0的默认引擎
  • WiredTiger:仅支持64位MongoDB

MongoDB两种引擎可以互相切换,我们可以在创建服务的时候指定引擎类型。语句如下:

MMAPv1引擎:

sc.exe create MongoDB binPath= "\"E:\Program Files\MongoDB\Server\3.0\bin\mongod.exe\" --service --directoryperdb --config=\"E:\Program Files\MongoDB\Server\3.0\mongod.cfg\"" DisplayName= "MongoDB" start= "auto"

!WiredTiger引擎:

sc.exe create MongoDB binPath= "\"E:\Program Files\MongoDB\Server\3.0\bin\mongod.exe\" --service --directoryperdb --storageEngine=wiredTiger --config=\"E:\Program Files\MongoDB\Server\3.0\mongod.cfg\"" DisplayName= "MongoDB" start= "auto"

MMAPv1引擎

MMAPv1预分配策略

MongoDB为了保证连续的存储空间,避免磁盘碎片问题会预分配空间。

工作方式是这样的:在创建数据库时,系统会创建一个名为[dbName].0的文件,该文件固定大小为64M,当该文件有一半以上被使用时,系统会再创建一个名为[dbName].1的文件,该文件大小是方才的两倍。以此类推,接下来创建的[db Name].n都是[dbName].n-1的两倍,最大直到2048M,此后,再次创建的文件大小都为2048M。因此如果数据足够多,64M, 128M, 256M, 1024M, 2048M, 2048M…大小的文件会被创建。

MongoDB记录数及占用空间测试

以下是不同记录数的情况下数据占用空间大小,每个文档的大小为240B,本人亲测:

记录数占用磁盘空间
200万 1G
600万 4G
1500万 6G
5000万 20G

空间释放

MongoDB自己不会释放空间,需要根据实际情况考虑策略。

我们删除MongoDB中的数据后,MongoDB不会释放空间,在此基础上再次插入数据后,数据将占用删除后的空间,即不再需要重新开辟空间。 
我们可以采用repair或compact命令主动回收,compact命令是对于某个collection(表),而repair是针对一个数据库。repaire命令执行时会停止数据库读写操作。(目前使用repair命令可实现空间释放,但是compact命令执行之后没有效果,需要再研究)。

WiredTiger

文档级锁(Document Level Locking)

!WiredTiger增加了文档级锁的概念,想比于MMAP的集合级锁,文档级锁可以让多个客户端同时修改同一个集合中的不同数据。

压缩(Compression)

使用!WiredTiger引擎,MongoDB可以压缩所有的集合和索引,相对于MMAPv1,MongoDB可以压缩最大80%的空间。 
下图可以看出!WiredTiger在存储方面的优势:

引擎记录数磁盘空间数据大小每个文档大小索引大小数据占用空间
MMAP 400万 1.95G 915M 240B 127M 1111M
WiredTiger 400万 103M 515M 135B 34M 68M

注:以上数据为本人测试结果,不同的文档会有不同的结果,大家可以自己试下。

MongoDB优缺点

MongoDB的优缺点网上有很多说法,根据我的理解总结如下:

优点

  • 性能优越,访问速度快。
  • 模式自由。
  • 内置GridFS,支持大容量存储。
  • 内置Sharding。
  • 开源免费且有官方支持。

缺点

  • 不支持事务。
  • 占用空间过大(这个使用WiredTiger引擎可以解决)。

javascript操作MongoDB

未完待续,MongoDB索引,副本集,分片,负载均衡,C#驱动