1、MongoDB简介
MongoDB
是一个基于分布式文件存储的数据库。由C++语言编写
。旨在为 WEB应用提供可扩展的高性能数据存储
解决方案。
MongoDB
是一个介于关系数据库
和非关系数据库
之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,
MongoDB
将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB文档
类似于JSON
对象。字段值可以包含其他文档,数组及文档数组。JSON
语句容易被解释
2、MongoDB优势
具备关系型优势,如:强大查询功能、强一致性、二级索引
具备非关系型优势,如:灵活模式、扩展性、性能
MongoDB特点:
- 自动复制
- 高可用
- 自动分片
- 水平扩展
Mongodb逻辑结构
Mongodb逻辑结构 | MySQL逻辑结构 |
---|---|
库(database) | 库(database) |
集合(collection) | 表(table) |
文档(document) | 数据行(ROW) |
3、MongoDB安装
1.系统环境
[root@db01 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@db01 ~]# uname -r
3.10.0-693.el7.x86_64
2.系统优化
- 文件描述符
当MongoDB处于频繁访问的状态时,如果shell启动进程所占用的资源设置过低的话,将会产生错误导致无法连接到MongoDB实例。需设置ulimit -n和ulimit -u的值大于65535
[root@db01 ~]# vim /etc/security/limits.conf
* - nofile 65535
* - nproc 65535
[root@db01 ~]# ulimit -n
65535
[root@db01 ~]# ulimit -n
65535
- 关闭大页内存
所有的noSQL产品都需要关闭大页内存来提高性能
[root@db01 ~]# vim /etc/rc.local
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never >/sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never >/sys/kernel/mm/transparent_hugepage/defrag
fi
3.创建所需用户和组
[root@db01 ~]# groupadd -g 800 mongod
[root@db01 ~]# useradd -u 800 mongod -g mongod
4.创建mongodb所需目录结构
[root@db01 ~]# mkdir -p /data/mongodb/{bin,conf,log,data}
5.下载mongodb并解压到指定位置
[root@db01 ~]# cd /opt/src/
[root@db01 src]# wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.2.16.tgz
[root@db01 src]# tar xf mongodb-linux-x86_64-rhel70-3.2.16.tgz
// 拷贝目录下bin程序至/data/mongodb/bin
[root@db01 src]# cp -a mongodb-linux-x86_64-rhel70-3.2.16/bin/* /data/mongodb/bin/
// 设置目录权限
[root@db01 ~]# chown -R mongod:mongod /data/mongodb
// 切换到mongod用户,设置环境变量
[root@db01 ~]# su - mongod
[mongod@db01 ~]$ echo "export PATH=/data/mongodb/bin:$PATH" >>.bash_profile
[mongod@db01 ~]$ source .bash_profile
6.mongod用户下启动mongodb
[mongod@db01 ~]$ mongod --dbpath=/data/mongodb/data --logpath=/data/mongodb/log/mongodb.log --port=27017 --logappend --fork
// 查看端口
[mongod@db01 ~]$ netstat -lntup |grep "27017"
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 50179/mongod
启动参数解释:
--dbpath=/data/mongodb/data # 指定mongodb数据目录(第一次启动会先初始化)
--logpath=/data/mongodb/log/mongodb.log # 指定mongodb的日志路径
--port=27017 # 指定mongodb端口号(默认为27017)
--logappend # 追加方式记录日志
--fork # 后台运行
--auth # 是否需要验证权限登录(用户名和密码)
--bind_ip # 限制访问IP
--shutdown # 关闭数据库
关闭数据库(谨慎执行)
[mongod@db01 ~]$ mongod --shutdown --dbpath=/data/mongodb/data --logpath=/data/mongodb/log/mongodb.log --port=27017 --logappend --fork
7.登录mongodb(默认没有用户名和密码)
[mongod@db01 ~]$ mongo
8.添加mongodb配置文件
上面那种手动指定data,log目录路径的方式显得很挫,下面就使用yaml格式编写的配置文件的方式启动mongodb
[mongod@db01 ~]$ vim /data/mongodb/conf/mongodb.conf
storage:
dbPath: "/data/mongodb/data"
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: "/data/mongodb/log/mongodb.log"
processManagement:
fork: true
net:
port: 27017
security:
authorization: enabled
*基础配置文件参数解释
# 系统日志相关
systemLog:
destination: file
path: "/data/mongodb/log/mongodb.log" #日志路径
logAppend: true #日志以追加模式记录
# 数据存储相关
storage:
dbPath: "/data/mongodb/data" # 数据路径的位置
journal:
enabled: true
# 进程控制相关
processManagement:
fork: true # 后台守护进程
pidFilePath: <string> # pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中
# 网络配置相关
net:
bindIp: <ip> #监听地址,如果不配置这行是监听在0.0.0.0
port: <port> #端口号,默认不配置端口号,则为27017
# 安全验证有关配置
security:
authorization: enabled #是否打开用户密码验证
9.指定配置文件,启动和关闭mongodb
// 关闭mongodb
[mongod@db01 ~]$ mongod -f /data/mongodb/conf/mongodb.conf --shutdown
// 启动mongodb
[mongod@db01 ~]$ mongod -f /data/mongodb/conf/mongodb.conf
3、MongoDB用户管理
MonogoDB
分为管理员用户
和普通用户
,并且还有个验证库
,建立用户时use到的库
(验证库),信息就存储在admin数据库下。在使用用户时,要加上验证库才能登录,对于管理员用户,必须在admin下创建。
基本语法说明:
user:用户名
pwd:密码
roles:
role:角色名
db:作用对象
常用role:root、readWrite、read
用户权限:
权限 | 说明 |
---|---|
Read | 允许用户读取指定数据库 |
readWrite | 允许用户读写指定数据库 |
dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
userAdmin | 允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户 |
clusterAdmin | 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。 |
readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
dbAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。 |
root | 只在admin数据库中可用。超级账号,超级权限 |
注意事项:
要想使用mongodb的用户功能,就需要在配置文件中,加入以下配置
[mongod@db01 ~]$ vim /data/mongodb/conf/mongodb.conf
....
security:
authorization: enabled
切换到mongo用户下,重启mongodb
[root@db01 ~]# su - mongod
[mongod@db01 ~]$ mongod -f /data/mongodb/conf/mongodb.conf --shutdown
[mongod@db01 ~]$ mongod -f /data/mongodb/conf/mongodb.conf
3.1、Mongodb创建超级管理员
1.创建一个用户:root,权限:超级账号
> use admin
> db.createUser(
{
user: "root",
pwd: "root123",
roles:[ {role: "root",db: "admin"} ]
})
创建管理员角色用户的时候,必须到admin下创建,验证用户(返回值为1则用户创建成功)
2.查看用户是否创建成功
> db.auth('root','root123')
1
3.2、MongoDB创建读写用户
1.创建一个用户:dba,权限:读写
> use admin
> db.createUser(
{
user: "dba",
pwd: "dba123",
roles:[ {role: "readWriteAnyDatabase",db: "admin"} ]
})
查看用户是否创建成功
> db.auth('dba','dba123')
1
3.3、Moongodb指定库授权
现在有个场景,我们需要对指定的数据库进行用户授权,
创建:app数据库,权限:读写
1.超级管理员用户登录(创建用户肯定要用管理员用户去登录)
[mongod@db01 ~]$ mongo -uroot -proot123 admin
2.选择一个验证库/数据库(站在用户认证角度,数据库就是验证库)
> use app
3.创建用户
> db.createUser(
{
user: "app_admin",
pwd: "app123",
roles:[ {role: "readWrite",db: "app"} ]
})
4.验证用户是否创建成功
> db.auth('app_admin','app123')
5.退出mongodb shell,验证登录
> exit
bye
// 输入刚刚创建的用户名/密码,以及验证库
[mongod@db01 ~]$ mongo -uapp_admin -papp123 app
6.查看当前登录的用户权限和验证库等相关信息
> db.stats()
{
"db" : "app",
"collections" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"ok" : 1
}
3.4、Mongodb用户登录
其实上面已经演示了mongodb用户如何登陆,这里在演示如何用超级用户
登录,以及本地/远程登录方式。
1.登录验证(需要指定验证库,上面在创建root用户的时候use的库)
// 本地登录
[mongod@db01 ~]$ mongo -uroot -proot123 admin
// 远程登录
[mongod@db01 ~]$ mongo -uroot -proot123 10.4.7.51/admin
2.查询mongodb中的用户信息(必须以root用户登录)
> db.system.users.find().pretty()
3.5、Mongodb用户删除
以root用户登录,use到验证库(admin)
[mongod@db01 ~]$ mongo -uroot -proot123 admin
> use app
> db.dropUser("app_admin")
对于Mongodb
来说,只要开启鉴权
,所有的DB访问操作
都需要通过权限检查
。而大致的操作流程
跟下图类似
Mongodb 的用户
归属于某个数据库,用户需要在所属的数据库中进行鉴权;- 一旦通过
鉴权
,当前的会话(连接)中所有操作将按照用户被赋予的角色权限执行检查。
4、MongoDB基本操作
Mongodb 默认存在的库:
- test库:默认存在的库
- admin库:系统预留库,mongodb系统管理库
- local库:本地预留库,存储关键日志
Mongodb 命令种类:
数据库对象:库(database),表(collection),数据行(document)
注意:下面所有基础命令操作都使用超级用户
4.1、Mongodb基础命令
//查看命令操作
> db.help
// 查看当前db版本
> db.version()
// 查看数据库
> show databases
> show dbs
// 查看集合/表
> show tables
> show collections
// 创建数据库
> use case
//查看当前库的情况
> db.stats()
// 查看当前通过何种方式连接到数据库
> db.getMongo()
// 退出当前数据库视图
> exit
4.2、Mongodb库操作
1、创建数据库
当use的时候,系统就会自动创建一个数据库。
如果use之后没有创建任何集合。
系统就会删除这个数据库。
2、删除数据库
如果没有选择任何数据库,会删除默认的test数据库
> use test
> db.dropDatabase()
{ "ok" : 1 }
5、Mongodb集合及文档操作
当插入一个文档时,一个集合(collections)就会自动创建
文中创建一个user集合,然后在该集合下对其增删改查操作
5.1、创建库和集合
//先进入到库
> use case
// 创建集合
> db.createCollection('user')
{ "ok" : 1 }
// 查看集合
> show collections
user
5.2、创建文档并插入数据
插入数据的时候会自动生成主键_id
> db.user.insert({name:"Jack",age:20,sex:"M",hobby:["basketball","run"]})
WriteResult({ "nInserted" : 1 })
> db.user.insert({name:"Xander",age:25,sex:"M",hobby:["football","run","billiards"]})
WriteResult({ "nInserted" : 1 })
5.3、查询集合数据
// 查询所有记录(默认每页显示20条记录,用it迭代命令查询下一页)
> db.user.find()
{ "_id" : ObjectId("5eb2787fe4401ef3d2c65107"), "name" : "Jack", "age" : 20, "sex" : "M", "hobby" : [ "basketball", "run" ] }
{ "_id" : ObjectId("5eb2789ce4401ef3d2c65108"), "name" : "Xander", "age" : 25, "sex" : "M", "hobby" : [ "football", "run", "billiards" ] }
// 每页显示1条记录
> DBQuery.shellBatchSize=20
20
// 查询所有记录,并格式化输出
> db.user.find().pretty()
{
"_id" : ObjectId("5eb2787fe4401ef3d2c65107"),
"name" : "Jack",
"age" : 20,
"sex" : "M",
"hobby" : [
"basketball",
"run"
]
}
{
"_id" : ObjectId("5eb2789ce4401ef3d2c65108"),
"name" : "Xander",
"age" : 25,
"sex" : "M",
"hobby" : [
"football",
"run",
"billiards"
]
}
// 查看第1条记录
> db.user.findOne()
{
"_id" : ObjectId("5eb2787fe4401ef3d2c65107"),
"name" : "Jack",
"age" : 20,
"sex" : "M",
"hobby" : [
"basketball",
"run"
]
}
// 查询集合总的记录数
> db.user.count()
2
5.4、多条件查询集合数据
查询 name = Jack 的记录
> db.user.find({name:"Jack"})
查询 age > 25 的记录
> db.user.find({age:{$gt:25}})
查询 age < 25 的记录
> db.user.find({age:{$lt:25}})
查询 age >= 25 的记录
> db.user.find({age:{$gte:25}})
查询 age <= 25 的记录:
> db.user.find({age:{$lte:25}})
查询 age >= 10 并且 age <= 30 的记录
> db.user.find({age:{$gte:10,$lte:30}})
查询 name 中包含 'X' 的数据(模糊查询)
> db.user.find({name:/X/})
查询 name 中以 'X' 开头的数据
> db.user.find({name:/^X/})
查询 name 中以 'r' 结尾的数据
> db.user.find({name:/r$/})
查询指定列数据
> db.user.find({},{name:"Jack"}) // 查询name列数据 第一个字段为查询条件
查询指定列,name,age数据,且 age > 20
> db.user.find({age:{$gt:20}},{name:true,age:true})
升序、降序排序
> db.user.find().sort({age:1}) // 升序
> db.user.find().sort({age:-1}) // 降序
查询前2条数据
> db.user.find().limit(2)
查询后5条数据
>db.user.find().skip(5)
查询1-10之间的数据
// 可用于分页,limit 是 pageSize,skip 是第几页 * pageSize
> db.user.find().limit(10).skip(1) // 10 之前,1之后,即 1-10 之间
或者/or 查询,查询 age = 28,或者 age = 29 的数据
> db.user.find({$or:[{age:28},{age:29}]})
统计 age > 21 的数据的数量
> db.user.find({age:{$gt:21}}).count()
5.5、查看集合存储信息
// 查看集合的存储信息
> db.user.stats()
// 集合中索引+数据压缩存储后的大小
> db.user.totalSize()
65536
// 集合中数据压缩存储的大小
> db.user.storageSize()
32768
5.6、批量插入数据
> for(i=0;i<10000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()})}
5.7、删除集合
// db.collertions.drop,collertions指定集合名
> db.user.drop()
// 删除集合中所有记录
> db.user.remove({})
5.8、重命名集合
> db.user.renameCollection("student")
{ "ok" : 1 }
> db.getCollectionNames()
[ "student" ]