Fork me on GitHub

MongoDB

https://www.jikexueyuan.com/course/mongoDB/

NoSQL数据库:NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",指的是非关系型的数据库

mongodb官网:https://www.mongodb.com/
https://docs.mongodb.com/manual/

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

http://www.runoob.com/mongodb/mongodb-tutorial.html

NoSQL保证数据的最终一致性,数据由更新延迟

CAP理论

适用场景:数据缓存;json格式数据存储;高伸缩性场景;
MongoDB更多适合大数据量、高并发、弱事务的互联网应用,其内置的水平扩展机制提供了从几百万到十亿级别的数据处理能力,可很好的满足Web2.0和移动互联网应用的s数据存储要求。

MongoDB由C++编写,支持32位(2G限制)和64位应用,是一个基于分布式文件存储的开源数据库系统。

MongoDB3.0特性:

  1. 加入WiredTiger存储引擎:
    开源的存储引擎;为现代硬件设计:多核CPU,充分利用内存/芯片级缓存;RAM/SSD/HDD;为大数据设计:高性能,低延迟,高并发稳定性
  2. MMAPv1:内存映射存储引擎,为默认引擎 ,提供了Collection锁;无缝迁移MMAP
  3. 可插拔引擎API
  4. 基于Web的可视化管理工具:Ops Manager

MongoDB数据模型
文档:本质上是一种类JSON的BSON格式的数据,可以理解为在JSON基础上添加了一些新的数据类型,包括Date,正则表达式等。
BSON官网:http://bsonspec.org/
BSON是由一组组键值对组成,具有轻量性、可靠性和高效性3个特征。可遍历性是MongoDB将BSON作为数据存储的重要原因
使用文档时需要注意以下事项:
MongoDB中写操作的原子性限制在文档级别;
单个文档占用的存储空间不能超过16MB;
MongoDB会尽量保持文档被插入时键值对的顺序;
关于文档命名需要注意的事项:
_id是系统保留的关键字,他是默认的主键,该值在集合中必须唯一,且不可更改;
键不能包含空字符或\0,这个字符用于表示键的结尾;
不能以$开头且不能包含点号.
键是区分大小写的且不能重复

集合:把一组相关的文档放到一起组成了集合,MongoDB的集合是模式自由的,一个集合里面的文档可以是各式各样的
MogoDB提供了一些特殊的集合:capped collection、system.indexes、system.namespaces等
集合命名需注意:
集合名不能是空字符串;
集合名不能包含空字符串或\0,该字符表示集合名的结尾
集合名不能以"system."开头,此前缀是系统本身保留的
集合名不能包含$字符,但是可以包含点号.

数据库:多个文档组成集合,多个集合组成数据库。一个MongoDB实例可承载多个数据库,每个数据库有独立的权限,在磁盘上,不同的数据库也可放置到不通目录
数据库命名规则:
不能是空字符串;不能以$开头;不能包含空字符串和点号.;数据库名称区分大小写;建议数据库名全部使用小写;数据库名最长64字节;不要与系统保留数据库名相同

命名空间:把数据库名添加到集合名前面,中间用点号连接,得到集合的完全限定,就是命名空间
因为点号可以出现在集合名字中,如:jike.blog.posts 和 jike.blog.authors,可以将posts和authors看作是blog集合的子集合,blog集合甚至可以不存在
使用子集合的方式,可以是我们更好的组织数据,使数据结构更加清晰明了

MongoDB数据类型
基本数据类型
null:表示空值或者不存在的字段
布尔:true/false
数据类型:32-int,64-int,64-double,注意:JavaScript只支持64位浮点数
字符串类型:使用UTF-8对字符串进行编码
二进制数据:可以保存由任意字节组成的字符串,如:图片、视频等
正则表达式类型:主要用于查询,使用正则表达式作为限定条件
Date类型:是一个64位整数,它代表距Unix epoch:1970-1-1的毫秒数,MongoDB在存储时间是现转换为UTC时间,北京时间=UTC+8小时,MongoDB Shell会根据本地时间 设置显示日期时间
Timestap:32bit Unix epoch + 32bit自增序数,只供MongoDB数据库服务内部使用,用于记录操作的详细时间
ObjectId:由24个16精制字符组成,每个字节存储两位16精制数字,总共需12字节存储空间=4字节时间戳+3字节机器标识+2字节pid+3字节计数器,ObjectId(),getTimestamp(),valueOf()
数组:使用方括号来表示的一组值,数组中可以包含不通数据类型的元素,针对数组,MongoDB提供了许多操作符,如:pop,pop,push,pull,pull,slice,$addToSet等;MongoDB可自动为数组元素建立MultiKey索引
内嵌文档:文档可以作为键的值,这样的文档成为内嵌文档。内嵌文档可以使数据不用保存成扁平结果的键值对,从而使数据组织形式更加自然。

内嵌文档模式VS引用文档模式
子文档比较小或变化不频繁,则使用内嵌文档模式,否则使用引用文档模式

MongoDB自动将_id字段设置为主键

MongoDB Shell:是MongoDB自带的JavaScript Shell,随MongoDB一起发布 =JavaScript V8解释器+MongoDB客户端

help查看帮助
执行脚本
直接执行:mongo [–quiet] script.js
交互执行:load(“script.js”)
执行命令行程序:run(“ls”)
.mongorc.js文件,默认会加载
编辑复合变量EDITOR:在.bashrc中添加后source生效

1
2
#EDITOR
EDITOR=/usr/bin/vim

即可使用editor编辑文档

http://www.runoob.com/mongodb/mongodb-intro.html
Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。

MongoDB数据库安装:

  1. 下载安装文件解压缩并添加bin目录到环境变量
  2. 创建一个data目录,然后在data目录里创建db目录、logs目录
  3. 启动服务端
  4. 启动客户端:mongo
  5. windows下可以将MongoDB做成系统服务

mac
临时添加环境变量:export PATH=/usr/local/mongodb/bin:PATH /.bashprofile,exportPATH=PATH 编辑~/.bash_profile,添加:export PATH=PATH:/usr/local/mongodb4/bin/:$PATH 即可永久添加环境变量

连接MongoDB数据库:./mongo + 服务器IP:端口号/数据库名
关闭MongoDB服务在 ./mongo 进入控制台后,输入 use admin,然后输入 db.shutdownServer()

Mongodb可以通过命令行方式和配置文件的方式来启动:
这两种方式都是在前台启动Mongodb进程,如果Session窗口关闭,Mongodb进程也随之停止。
不过Mongodb同时还提供了一种后台Daemon方式启动,只需要加上一个"–fork"参数即可,用到了"–fork"参数就必须启用"–logpath"参数
通过命令行: ./bin/mongod --dbpath=/data/db --fork --logpath=/data/logs/mongodb.log
配置文件方式:./bin/mongod -f mongodb.conf 或 ./bin/mongod --config mongodb.conf //-f 后面写要使用的配置文件
./bin/mongod --shutdown -f mongod.conf

1
2
3
4
port=27017
dbpath=/usr/local/mongodb/data/
logpath=/usr/local/mongodb/log/mongodb.log
fork = true

命令行操作:
use mytetDB //数据库如果不存在则创建
save时如果给定了_ObjectId则更新创建整条记录;如果要更新部分字段则使用update方法使用$set
db.dropDatabase()
db//显示当前数据库
show dbs
show collections

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

MongoDB GridFS文件系统
分布式文件系统:将固定存储于单台机器上的文件系统,扩展到多台机器上,每个节点负责存储部分数据,众多的存储节点组成一个文件系统网络,各个节点通过网络进行通信和数据传输

当存储文档大于16M时,可以考虑使用GridFS
GridFS:是MongoDB制定的如何在数据库中存储大文件的规范,MongoDB并没有实现GridFS,而是交由客户端驱动程序实现
GridFS使用两个集合(collection)存储文件。一个集合是chunks, 用于存储文件内容的二进制数据;一个集合是files,用于存储文件的元数据。
使用fs.files存储文件的元数据,包含字段如下:
使用fs.chunks存储以255K进行分割的文件块,包含字段如下:
GridFS适用于如下场景:
存储用户产生的文件且文件数量比较大;需要文件的自动备份和分布式存储;需要访问文件的部分内容;存储16MB以上的文件
mongofiles是MongoDB安装包中提供的一个工具,专门用来存取文件,包括查询所有文件、查看文件、上传一个文件、获取一个文件、按照_id来获取文件、按文件名删除文件、按_id删除文件。
mongofiles --help其实有四个主要命令,分别为:
put —存储命令
get —获取命令
list —列表命令
delete —删除命令

MongoDB聚合管道:聚合操作主要用户批量数据处理,往往将记录按条件分组,然后在每组上分别进行一系列操作,如:求和、求最大小值等
聚合操作能够对记录进行复杂处理,主要为数理统计和数据挖掘。
MongoDB提供了3种聚合操作方式:
聚合管道(Aggregation Pipeline):MongoDB Shell使用db.collection.aggregate([{…}])来构建和使用聚合管道
$project:用于修改文档的结构,可以重命名、增加或删除文档字段
match:match:用于过滤文档,在match中不能使用$where,尽量出现在管道的前面,方便借助索引加快查询
$group:将集合中的文档进行分组,此分组在内存中进行,最大100M,可通过allowDiskUse启用磁盘交换处理
$sort:将集合中的文档进行排序,此分组在内存中进行,最大100M,可通过allowDiskUse启用磁盘交换处理
$skip:跳过指定数量的文档
$unwind:将文档按照数组字段拆分成多条文档,每条文档包含数组的一个元素
$geoNear:按照由近到远顺序输出接近某一地理位置的文档
out:""""使1out:将聚合结果存储到集合中,参数为集合名称 。。。 聚合管道表达式:阶段操作符可以看作是"键",所对应的"值"称为管道表达式,管道表达式可以看作是管道操作符的操作数,管道表达式是一个文档结构,由字段名、字段值和表达式操作符组成。 聚合管道使用优化: 1将match、$sort放到管道开始阶段,有利于利用索引提高文档处理效率
2提交过滤可减少流经后续阶段的文档数量
聚合管道的限制:
1返回文档结果不能超过16M,可通过返回一个游标或存储到集合中跳过此限制
单目的聚合操作
count
distinct
group
MapReduce编程模型

mongoimport可以导入集合

MongoDB数据更新
文档插入和删除:insert、update、delete
Bulk函数:Bulk可将多个数据更新操作放到一个待执行的列表中批量来执行,顺序执行的Bulk(按添加顺序执行,一个有问题则退出)和并执行的Bulk(随机方式并行)
1初始化Bulk:
并行:db.集合名.initializeUnorderedBulkOp()
顺序:db.集合名.initializeOrderedBulkOp()
2 bulk.inset({…})
3 bulk.execute()

MMAPv1的内存分配策略:如果一个更新操作超过了文档在磁盘上预分配的空间,MongoDB会重新在磁盘上为其分配一块更大的连续空间。使用"2的N次方"的方式分配内存,如:32,64,128,256…2M,4M…
优点:1有利用内存的重用,降低系统碎片的数量;2减少数据移动频率,提高系统数据写效率

文档修改
WriteResult = db.集合名.update(query,obj,upsert,multi)
query:查询条件,相当于where
obj:更改的内容,相当于SQL中的set语句
upsert:当query的文档不存在时是否插入一条新文档
multi:当query返回多个文档时是否一次更新满足条件的所有文档,默认只更新一条

内嵌文档的修改:

  1. 修改整个内嵌文档:{$set:{field1:新内嵌文档}}
  2. 修改内嵌文档的某个字段:{$某个修改操作符:{field1.field2:value}}

数组元素:MongoDB提供了大量的特定操作符,使得数组既可以作为栈、队列等有序对象使用,也可当作集合等无序对象来使用

MongoDB的写安全机制
写过程:使用update、save等操作数据集合中数据时,只是修改了数据再内存中的映像,数据更新并没有同步地保存到磁盘上,而且更新内存中数据之前,更新操作会被记录到journal日志文件中,
每隔100ms将内存journal中的日志写到磁盘journal日志文件中 ,每隔60s将内存中修改的数据写会到磁盘上
写入安全级别:写入安全Write Concern是一种客户端设置的,用于控制写入安全级别的机制,通过写入安全机制可提高数据的可靠性。
分为四个级别,分别是:
非确认式写入Unacknowledged:写操作不会返回结果,所以无法知道是否写入成功;但速度快、效率高、无阻塞
确认式写入Acknowledged:写操作必须得到MongoDB服务器的写入确认,如果失败,会返回异常
日志写入Journaled:写操作要等到操作记录存储到Journal日志文件后才返回结果
复制集确认写入Replica Acknowledged:写操作不仅要得到主节点的写入确认,还要得到从节点的写入确认,可以设置写入节点的个数(包含主节点)

journal日志相当于oracle中的redo日志文件,用户故障恢复和持久。Journal默认100ms刷新一次,所以最多丢失100ms数据
文件位于journal目录中,只能以追加方式添加数据,文件名以"j._"开头,超过1G会自动创建新的;数据库正常关闭时,数据库服务会自动清空journal目录下所有文件

设置写安全操作级别,其实就是在写操作的性能和可靠性间取一个权衡;使用的写操作级别越高,时间越长,可靠性越高

使用writeConcern函数作为更新函数的一个参数来设置写安全级别,如:db.集合名称.insert({name:“joe”},{writeConcern:{j:true}}),writeConcern函数参数如下:
w选项,可选择0,1,2等整数值及"majority",0-非确认式写入 1-确认式写入(未启用复制集)/主节点确认式写入(启用了复制集),>1只能用于复制集,2-数据至少写到1个从节点后返回,majority 只能用于复制集,表示更新操作用到大多数从节点
j选项,设置为true来使用journaled日志安全级别
wtimeout选项,用于设置超时单位为毫秒
以上选项可组合使用

数据MongoDB数据查询
Cursor = db.集合名称.find(query,fields,limit,skip)
query:查询条件,相当于where
fields:用于字段映射,语法格式:{field:0}(0表示返回结果不包含此字段)或{field:1}(1表示返回结果不包含此字段),默认包含_id字段,相当于select中后面需要的字段
limit:限制查询结果集的数量,指定查询返回结果的数量上限,也可通过limit()实现
skip:跳过一定数据量的结果,设置第一条返回文档的偏移量,也可通过skip()实现
find查询只能正对一个集合;返回的集合默认是无序的

db.集合名称.findOne()只返回第一条数据

查询操作符
比较查询操作符
逻辑查询操作符
元素查询操作符
$where查询操作符:可以将JavaScript表达式的字符串或JavaScript函数作为查询语句的一部分,在js表达式和函数中,可使用this或obj来引用当前操作的文档,当js表达式或函数返回true时,才会返回当前文档

内嵌文档与数组查询
内嵌文档查询
1查询整个内嵌文档:当内嵌文档的键值对数量和键值对顺序都相同时,才会匹配
2查询文档的某个字段:需要使用.号操作符,如:db.user.find({“address.city”:“BeiJing”})
数组查询
1查询整个数组:当数组元素内容和数组元素顺序都相同时,才会匹配
2查询数组中的元素(普通元素):
A与位置无关,查询数组中含有某个值的文档,如:db.user.find({score:80})
B与位置有关,按照指定的数组索引查询数组元素的值,如:db.user.find({‘scores.2’:80})
3查询数组中的数组元素是文档时,查询数组元素有两种情况
A与位置无关,查询数组中满足条件的子文档元素,如:db.user.find(‘scores.成绩’:95)
B与位置有关,按照指定的数组索引查询数组子文档,如: db.user.find(‘scores.2.成绩’:95)

MongoDB查询结果返回过程:find函数查询结果是以多条文档的形式分批来返回查询结果的,返回的文档会缓存到内存中,Cursor在一批数据回来之后遍历,下一批没来时会自动发起下一批请求,然后继续遍历

MongoDB游标:用来遍历结果集中的数据。
游标的生命周期:创建、使用、销毁
游标可能会返回那些由于体积变大而被移动到集合末尾的文档而重复返回,可通过对查询快照的方式解决此问题,语法为:db.collection.find().snapshot().
使用快照之后,查询就会在_id索引上来遍历执行,这样就可以保证每个文档只被返回一次,从而保证获取结果的一致性。

模糊查询:查询条件可以使用正则表达式实现模糊查询,支持正则表达式操作符和正则表达式对象两种。
正则表达式操作符:$regex

findAndModify函数使用执行分为find和update两步,但可以保证操作的原子性

MongoDB是为分布式存储而设计,_id主键默认使用ObjectId类型的值,比自增方式更适合分布式环境,所以MongoDB默认不支持字段自增长功能

MongoDB索引:数据库索引是对数据表中一列或多列的值进行排序的一种数据结构,使用索引可快速访问数据表中的特定信息。MogonDB索引不仅提高文档查询速度,还有利于排序时节省内存资源。
MongoDB所有的索引信息被保存在system.indexes集合中,且默认总为_id创建单字段升序具有唯一属性的索引,可通过db.system.indexes.find()查看所有索引
MongoDB可在单个字段上建立索引,字段可以是普通字段、整个文档以及子文档的某个字段
对于复合索引,MongoDB支持前缀匹配
为确保查询只使用复合索引,可以使用映射来指定不要返回_id字段(除非它是复合索引的一部分)
多键索引:是对数组类型建立的索引,实际上是对数组的每个元素建立索引,而不是数组本身建立索引;当数组元素是文档时,可为文档的某个字段建立多键索引
哈希索引:只支持等值查询,不支持范围查询,主要用于分片的集合上,可以作为片键来使用,能将数据比较均匀的分散存储在各个分片上,如:db.集合名.createIndex({name:“hashed”})

MongoDB索引的属性
唯一索引:可以确保集合的每一个文档的索引字段都有唯一的值,不会出现重复值,如:db.集合名.createIndex({name:1},{unique:true}),在非空集合创建唯一索引可能会因为已有重复值而失败,可添加dropBups:true删除重复文档
稀疏索引:只会为索引字段存在的文档建立索引,即使索引字段的值为null,但不会为索引字段不存在的文档建立索引
TTL(Time To Live)索引:为文档设置一个超时时间,当达到预设置的时间后,该文档会被数据库自动删除,但删除可能有延迟。这种类型的索引对缓存问题非常有用。只能建立在单独非_id字段
创建了TTL索引后,MongoDB会有一个后台线程来管理文档;在复制集上建立的TTL索引,TTL后台线程只会运行在主节点上

MongoDB索引的管理
索引的默认命名规则:keyname1_dir1_keyname2_dir2…,其中keynameX是索引字段的名称,dirX是索引方向,1升序-1降序,也可自定义命名
创建索引:db.集合名.createIndex(keys,options),返回值为一个文档类型。索引一旦创建就不能修改,创建后可通过db.集合名.getIndexes()查看集合所拥有的索引,创建索引有两种方式:
1foreground:阻塞所有对数据库的读写请求,直到索引创建完成,为默认方式
2background:创建索引时,如果有新的数据库请求,创建过程会暂停
删除索引:db.集合.dropIndex(index)
查询优化器:用来优化查询过程,通过比较返回100条文档速度得到最佳查询计划
explain函数:能够提供大量与查询有关的信息,可以很好的评估索引性能,帮助优化索引的使用策略。db.集合.find().explain(mode),支持3种模式:
1queryPlanner:查询计划,默认
2executionStatus:查询性能统计
3allPlansExecution:所有计划统计信息(最优与被拒绝的计划)
explain返回结果使用由多个阶段(Stage)组成的树形结构来表示查询计划,查询计划自下而上执行,树的叶节点用来访问文档或索引,内部节点处理下层节点返回文档或索引,根节点输出查询结果
hint函数:强制MongoDB使用特定索引

MongoDB特殊索引
地理空间索引:对地理位置数据建立索引,MongoDB支持两种2dsphere球面索引和平面2d索引
2dSphere球面索引
2d平面索引

全文索引:又称为倒排索引,用于在大量文本中对每一个词组建立索引,指出该词在整段文本中出现的位置和次数,此技术主要用于搜索引擎和站内搜索等。
一个集合只能有一个全文索引

java对mongodb的使用
集群搭建:mongodb分布式集群搭建手记

学习:http://www.cnblogs.com/huangxincheng/archive/2012/02/18/2356595.html

分析没有默认的,因为你还没给root设置密码,第一个 user 是在 admin 组 ,所以他可以给 root 设置密码 , so
sudo passwd root

Language Support

http://blog.csdn.net/sinat_35418761/article/details/53241481

http://www.2cto.com/database/201504/395442.html
http://www.myexception.cn/operating-system/1685604.html

https://my.oschina.net/chinacaptain/blog/465723

http://api.mongodb.com/java/current/

MongoDB是什么
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
他的特点:高性能、易部署、易使用,存储数据非常方便。

Bson:Binary Serialized Document Format,是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型

本文标题:MongoDB

文章作者:行锋

发布时间:2019年02月14日 - 16:02

最后更新:2019年02月14日 - 16:02

原始链接:https://chetaofeng.github.io/2019/02/14/数据库-2018-12-10-MongoDB/

许可协议: 署名-非商业性使用 转载请保留原文链接及作者

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!