一.为什么选择mongoDB
开源的NoSql数据库。
1.无数据结构限制:没有表结构概念,不需要事先定义表结构就可以使用,每条记录可以有完全不同结构。
2.完全的索引支持
3.方便的冗余与扩展:复制集保证数据安全,分片扩展数据规模。
4.良好的支持:完善的文档,齐全的驱动支持。
二.mongoDB安装与配置
1.mongoDB运行环境
mongoDB环境:64位linux(也可以是windows环境)
mongoDB版本:2.6.5
ssh工具:xshell
2.编译mongoDB文件
下载mongoDB安装包后放到linux服务器上进行解压并编译
进入解压后的安装文件输入编译命令:scons all (如果机器的CPU有多个,可以这样来加速编译过程 :scons all -j cpu核数)
注意:如果编译过程出错可以自行安装所需依赖,如多次编译不能通过,可在官网下载编译好的二进制直接执行。
讲下编译后的几个重要文件:
mongod:mongoDB数据库的执行程序,之后的数据库部署就是使用这个程序进行。
mongo:一个用来链接mongoDB服务器的客户端,之后对数据库的所有操作需要先使用这个客户端连接到mongoDB服务器后才能进行。
mongoimport,mongoexport:用来做mongoDB的导入导出。
mongodump,mongorestore:与上面两个导入导出类似,但导出的是二进制数据,不能被直接读取,一般用来做数据的备份与恢复。
mongoplog:用来做操作日志的回放,是mongoDB复制集中用来记录操作记录的数据集合。
mongostat:用来查看mongoDB服务器的各种状态。
3.搭建mongoDB服务器
A.创建安装目录:mkdir mongodb_simple
B.进入安装目录后创建如下文件:
data:用来存储数据库的数据文件。
log:存储数据库的日志文件。
conf:存储数据库的启动配置文件。
bin:存储数据库的二进制文件。
C.将编译好的mongob程序拷贝到bin目录下
D.进入conf文件夹下编辑一个启动文件,命名为mongod.conf
以上ABC三个步骤的命令如下:
D.编辑mongod.conf,加入以下参数
port = 12345:指明mongoDB启动时要监控的端口。
dbpath = data : 指明mongoDB数据存储的目录,相对路径和绝对路径都可以。
logpath = log/mongod.log : 指明日志文件的路径。
fork = true : 在linux下表明这是启动了一个后台进程,这个参数在Windows无效。
E.启动mongoDB服务器
在安装目录下输入启动命令:./bin/mongod -f conf/mongod.conf (用-f指明启动时需要使用的配置文件)
4.连接mongoDB服务器
A.使用mongoDB编译时生成的客户端进行连接,即mongo客户端。
a.为方便使用,将mongo客户端拷贝到安装目录mongodb_simple的bin目录下,之后可用help命令查看客户端使用说明。
b.连接服务器命令:./bin/mongo 127.0.0.1:12345/test (没有设置用户名和密码所以不需要输入)
c.关闭服务命令:db.shutdownServer() (这个命令只有管理员admin才有权限执行,所以必须先把身份转换为admin)
B.使用各种驱动进行连接。
三.mongoDB基本使用
1.数据写入和查询
查询数据库列表:show dbs
使用数据库:use xx (不需要对数据库进行额外创建,mongod会在需要时自己创建数据库)
删除数据库:db.dropDatabase()
写入数据:db.集合名.insert({key:value}) (在mongoDB中将一张表称作一个集合,insert()括号中的参数为要写入的文档,文档格式为json ,即{key:value})
查询表列表 : show collections
查询表中的所有数据:db.集合名.find()
查询表中指定数据:db.集合名.find({key:value})
批量插入数据:for(i=n;i<k;i++)db.集合名.insert({key:i})
查询数据量:db.集合名.find().count() (skip(n) :过滤掉前n行数据;limit(n):限制返回n条数据;sort({key:value}) : 排序方式)
2.数据更新
db.集合名.update(查询条件,更新条件) (查询条件和更新条件分别为两个json格式的数据)
A.只有一个字段的情况:
B.有多个字段时只更新部分字段的情况:更新条件使用set操作符指定修改的字段,未指定的字段不变
3.更新不存在的记录
db.集合名.update(查询条件,更新条件,upsert) (upsert=true表明查找的记录不存在时自动创建一条,默认为false)
4.更新多条数据
A.为了防止不小心的update的误操作,在mongoDB中默认只会更新第一条找到的数据
B.更新多条记录:db.集合名.update(查询条件,更新条件,upsert,multi) (multi默认为false表明只更新找到的第一条记录,更新多条记录时设置为true即可)
5.数据删除
A.删除表中数据:db.集合名.remove({key:value})
B.删除表:db.集合名.drop()
6.创建索引
A.查看索引:db.集合名.getIndexes()
B.创建索引:db.集合名.ensureIndex({key:value}) (value不再代表值,而是代表方向,1表示正向排序,-1表示逆向排序)
四.mongoDB常见的查询索引
1._id索引
_id索引是绝大多数集合默认建立的索引。
对于每个插入的数据,mongoDB都会自动生成一条唯一的_id字段。
2.单键索引
单键索引是最普通的索引,不会自动创建。
值为一个单一的值,例如字符串,数字或者日期等。
3.多键索引
多键索引与单键索引都是用db.集合名.ensureIndex({key:value}) 命令创建的。
不同在于多键索引的值具有多个记录,例如数组.
插入以上记录后mongoDB便为x创建了一个多键索引。
4.复合索引
当查询条件不只一个时就需要使用复合索引。
5.过期索引
A.是在一段时间后会过期的索引。
B.在索引过期后,相应的数据会被删除。
C.适合存储一些在一段时间后会失效的数据如用户的登录信息,存储的日志。
D.创建方法:db.集合名.ensureIndex({time:1},{expireAfterSeconds:value}) (expireAfterSeconds表示过期索引的过期时间,值的单位为秒)
E.过期索引的限制:
a.存储在过期索引字段的值必须是指定的时间类型。
必须是ISODate或者ISODate数组,不能使用时间戳,否则不能被自动删除。
b.如果指定了ISODate数组,则按照最小的时间进行删除。
c.过期索引不能是复合索引,因为不能同时指定两个过期时间。
d.删除时间是不精确的。
删除过程是由后台程序每60s跑一次,而且删除也需要一些时间,所以存在误差。
6.索引属性
A.name指定索引名称
db.集合名.ensureIndex({},{name:" "})
B.unique指定索引唯一性
db.集合名.ensureIndex({},{unique:true/false})
C.sparse指定索引的稀疏性
db.集合名.ensureIndex({},{sparse:true/false}) (默认false表示插入文档时会为索引不存在的字段自动创建索引)
不能在稀疏索引上查找索引字段不存在的记录。
说明:
$exists操作符用来查找数据集合中一个字段存在或者不存在的记录
当用hint强制使用稀疏索引查找该字段不存在的记录时无法查找到记录
D.expireAfterSeconds指定过期索引的过期时间
五.全文索引
1.创建全文索引的方法
在mongoDB中每个数据集合只能创建一个全文索引。
全文索引与普通索引不同在于value不是1或者-1,而是固定的字符串text。
db.articles.ensureIndex({key:"text"})
db.articles.ensureIndex({key_1:"text",key_2:"text"})
db.articles.ensureIndex({"$**":"text"}) (当有多个key时选用这种方式表示创建一个大的全文索引)
2.如何使用全文索引查询
db.articles.find({$text:{$search:"coffee"}})
db.articles.find({$text:{$search:"aa bb cc"}}) (或查询)
db.articles.find({$text:{$search:"aa bb -cc"}}) (-cc表示不包含c)
db.articles.find({$text:{$search:"\"aa\" bb cc"}}) (将字符串用引号包含起来表示与查询,引号前加斜杠为了避免歧义)
3.全文索引相似度查询
$meta操作符:{score:{$meta:"textScore"}}
写在查询条件后面可以返回结果的相似度。
与sort一起使用可以达到很好的使用效果
4.全文索引的使用限制
A.每次查询只能指定一个$text查询
B.$text查询不能出现在$nor查询中 ($nor查询用来排查某些查询)
C.查询中如果包含了$text,hint不再起作用 (hint可以强制指定索引)
D.mongoDB全文索引还不支持中文
六.mongoDB的地理位置索引
1.2D索引:平面地理位置索引
db.collection.ensureIndex({w:"2d"})
位置表示方式:经纬度 [经度,纬度]
取值范围:经度 [-180,180] 纬度 [-90,90]
查询方式:
A.$near查询:查询距离某个点最近的100个点。可用$minDistance限制返回最大距离的点。
B.$geoWithin查询:查询某个形状内的点。
形状的表示:
a.$box:矩形使用
{$box:[[<x1>,<y1>],[<x2>,<y2>]]}
b.$center:圆形使用
{$center:[[<x1>,<y1>],r]}
c.$polygon:多边形使用
{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}
C.geoNear查询:$near查询的进化版
使用runCommand命令进行使用
db.runCommand(
{ geoNear:<collection>,
near :[x,y],
minDistance:(对2d索引无效)
maxDistance:
num:
...}
)
说明:
geoNear 指定集合的名字
near :指定坐标
num:限制返回的数目
说明:
dis:查找到的数据距离指定的坐标 [1,2] 距离多少
obj:查找到的文档
nscanned:扫描了哪些数据
time:花费的时间
maxDistance:最大的距离
avgDistance:平均距离
ok=1代表查询成功
2.2Dsphere索引:球面地理位置索引
db.collection.ensureIndex({w:"2dsphere"})
位置表示方式:
GeoJSON:描述一个点,一条直线,多边形等形状。
格式:{type:" " , coordinates:[<coordinates>]}
查询方式与2d索引类似,不同在于2Dsphere索引支持$minDistance
七.索引构建情况分析
索引的优势:加快索引相关的查询
索引的劣势:增加磁盘空间消耗,降低写入性能
如何评判当前索引构建情况:
1.mongostat工具:mongoDB自带的用来查看mongoDB运行状态的程序。(上文我们介绍编译出来的文件时可以看到这个程序)
可通过命令./mongostat --help 查看使用手册
./mongostat -h mongoDB服务器地址:端口号
输出参数介绍
inserts:当前mongoDB的插入数量,数量以每秒为单位
query:查询数量
update:更新的数量
delete:删除的数量
getmore:在进行mongoDB查询时不是每次都返回所有数据,当一次查询比较多的数据时只会返回一定量的数据,当在各种驱动中进行find不停遍历查询时mongoDB会执行getmore用来获取以后的数据。
command:执行命令的数量
flushes:查看mongoDB隔多久会把我们写到内存的数据刷到硬盘上,这个数据比较大时mongoDB的性能会比较差。
mapped,vsize,res:说明mongoDB占据的磁盘空间大小或申请的内存大小
faults:表示如果我们查询的数据没有提前被mongoDB加载到内存中就需要到硬盘上去读取,faults比较高时也会造成性能下降。
locked:锁的使用情况。
idx miss:查询没有命中索引的比例,当这个数据很高时说明索引创建有问题。
qr | qw :mongoDB读队列和写队列的情况,当这两个队列很长时mongoDB的性能会下降。
ar | aw :当前活跃客户端的数据
netIn,netOut:mongoDB使用网卡的输入输出流量
conn:mongoDB的连接数量
2.profile集合
profile集合是mongoDB的慢操作日志,在设置合适级别后会将相应操作记录下来
如果profile记录的数据非常大会比较明显降低系统的性能,因此profile一般用于上线前的测试以及刚上线的观察
A.db.getProfilingStatus() : 查看mongoDB当前的profile设置
B.db.setProfilingLevel() : 设置profile的级别 (级别=0时表示不记录任何操作,级别=1时配合slowms做为阈值,mongoDB会记录超过slowns的操作,级别=2时会记录任何操作)
C.查看profile集合记录的操作
如db.system.profile.find().sort({$natural:-1}).limit(1)
输出参数介绍:
op:操作类型
ns:查询的命名空间 ,格式为数据库名.profile集合名,如mydb.system.profile
query:find的查询条件
orderby:排序条件
cursorid:游标id,多次getmore的游标id是一样的
ntoreturn:返回的数据量
ntoskip:跳过的数据量
nscanned :扫描的索引数目
nscannedObjects:扫描的实体数目
millis:当前查询使用的时间
3.mongoDB日志
可在mongoDB的配置文件mongod.conf配置日志详细程度:verbose = vvvvv (最多配置5个v,v越多越详细)
4.explain分析
显示出本次查询的详细信息
如db.collection.find({key:value}).explain()
输出参数介绍:
cursor:使用的游标,一般跟索引相关 (cursor=BasicCursor表示没有使用索引)
其他输出字段跟profile集合类似。
八.mongoDB安全
1.开启权限认证
A.auth开启
在mongoDB配置文件mongod.conf里配置auth = true 开启权限认证
B.keyfile开启
2.创建用户:createUser(2.6之前为addUser)
输入参数介绍:
user:用户名
pwd : 密码
customData:对用户名,密码的说明,主要用于方便查看
roles:这个用户的角色 (role:角色类型(read读权限,readWrite读写权限,dbAdmin提供对指定数据库的管理权限,dbOwner拥有前面三个权限,userAdmin可以对其他角色的权限进行管理),db:这个角色创建在哪个数据库上)
3.用户角色详解
A.数据库角色(read,readWrite,dbAdmin,dbOwner,userAdmin)
B.集群角色(clusterAdmin,clusterManager...)
C.备份角色(backup,restore...)
D.其他特殊权限(DBAdminAnyDatabase)
4.创建用户角色:createRole
输入参数介绍:
_id:唯一的id
role:角色名字
db:数据库的名字
privileges:在数据库上的权限操作