MongoDB学习
MongoDB简介
是什么
- 基于分布犹文件存储数据库(就是一个数据库
- C++语言编写
- 支持的数据结构非常松散,是类似json的bson格式(后期插入修改数据写JSON)
JSON(JavaScript Object Notation,JS对象简谱)是一种轻量级的数据交换格式bson(二进制SON)
能干嘛
存放项目数据
实战工作开发写API接口(重要
等等
从哪下载
- windows版本下载: https://www.mongodb.org/dl/win32
- linux版本下载: https://www.mongodb.org/dl/linux
- 各版本下载: https://www.mongodb.com/try/download/community
版本说明
- 2.x
- 3.x (3.2、 3.4、 3.6)
- 4.x (4.2更佳的数据管理能力、更强的分布式架构、多文档事物等)
- 写这篇教程的时候最新版是 4.4
安装
Liunx系统
1 | #步骤1:下载 |
Win系统
步骤1: 下载 https://www.mongodb.com/download-center/community 选择windows、zip
步骤2: 解压
步骤3: 创建服务
1 | bin/mongod.exe --install --dbpath 磁盘路径 --logpath 日志路径 |
注意:
- 通过管理员身份运行DOS窗口否则没有权限创建失败
- 需要提前
创建数据和日志存放目录
、比如在bin同级目录下创建data 、logs目录
这是我的命令:
1 | D:\Programs\MongoDB\bin>mongod --install --dbpath D:\Programs\MongoDB\data --logpath D:\Programs\MongoDB\logs\mongodb.log |
步骤4: 启动服务
可以在windows中的服务中找到MongDB
1 | net start mongodb |
步骤5: 登录(验证是否安装成功)
输入mongo
1 | D:\Programs\MongoDB\bin>mongo |
基本语法
- 创建服务:
bin/mongod. exe --install -- dbpath 磁盘路径 -- logpath 日志路径
- 删除服务:
bin/mongod. exe --remove
- 启动服务:
net start mongodb (注: service 服务名d restart/stop/start)
- 关闭服务:
net stop mongodb
基本操作
基本概念
- 生活中:仓库、架子、物品
- 计算机:数据库(database) 、集合(collection) 、数据/文档(document)
查看数据库
语法:show databases
缩写:show dbs
效果:
选择数据库
语法: use 数据库名
1 | > use admin |
隐式创建
: 在mongodb选择不存在的数据库不会报错,后期当该数据库有数据时,系统自动创建
查看集合
语法: show collections
1 | > use admin |
创建集合
语法: db.createCollection("集合名")
1 | > use zykj |
删除集合
语法: db.集合名.drop()
1 | > show collections |
思考:如何删除数据库?
回答:
- 通过
use语法
选中数据库 - 通过
db.dropDatabase()
小总结
数据库(查看、创建、选择、删除
1 | 查看: show databases |
集合(查看、创建、删除
1 | 查看: show collections |
文档增删改查(CURD)
明确需求
数据库主要用来存放项目数据
然后我们已经学会了数据库和集合的创建
思考: 如何实现集合中数据的增删改查呢?
回答: 通过MongoDB语法即可
增 C
语法: db.集合名.insert(JSON数据)
说明: 集合存在-则直接插入数据,集合不存在-隐式创建
练习: 在test2数据库的c1集合中插入数据(姓名叫webopenfather年龄18岁)
1 | use test2 |
结果:
1 | > use test2 |
多学一招:_id的组成:时间戳+机器码+PID+计数器
思考1: 是否可以自定义_id值?
回答:可以,只需要给插入的SON数据增加
_id
键即可覆盖(但实战强烈不推荐db.c1.insert({_id:1, uname:"webopenfather", age:18})
思考2: 如何一次性插入多条记录?
回答:传递数据,数组中写一个个JSON数据即可
1
2
3
4
5
6
7 db.c1.insert([
{uname: "z3",age: 3},
{uname: "z4",age:4},
{uname : "w5",age: 5}
])
含义:—次性插入3条数据到c1集合
思考3:如何快速插入10条数据
回答: mongodb底层使用JS引擎实现的,所以支持部分js语法
因此: 可以写for循环
1
2
3 for (var i=1; i<=10; i++){
print(i)
}需求:在test2数据库c2集合中插入10条数据,分别为a1 a2 … a10
1
2
3
4 use test2
for(var i=1;i<=10;i++){
db.c2.insert({uname: "a"+i, age: i})
}
结果
1 | > for(var i=1;i<=10;i++){ |
查 R
基础语法: db.集合名.find(条件[,查询的列])
条件
- 查询所有数据
- 或者不写
- 查询age=6的数据 {age:6}
- 既要age=6又要性别=男 {age:6 ,sex:’男’}
查询的列(可选参数
- 不写 – 这查询全部列 (字段
- {age:1} 共显示age列 (字段
- {age:0} 除了age (字段都显示
- 留心:不管你怎么写系统自定义的 _id 都会在
升级语法:
1 | db.集合名.find({键:值}) 注:值不直接写 |
运算符 | 作用 |
---|---|
$gt | 大于 |
$gte | 大于等于 |
$lt | 小于 |
$lte | 小于等于 |
$ne | 不等于 |
$in | in |
$nin | not in |
练习1:查询所有数据
1 | > use test2 |
练习2:查询年龄大于5岁的数据?
1 | > db.c2.find({age:5}) |
练习3:查询年龄是5岁、8岁、10岁的数据?
1 | > db.c2.find({age:{$in:[5,8,10]}}) |
练习4:只看年龄列,或者年龄以外的列(_id别管它)?
1 | > db.c2.find({},{age:1}) |
改 U
基础语法: db.集合名.update(条件,新数据[,是否新增,是否修改多条])
1 | 是否新增:指条件匹配不到数据则插入(true是插入,false否不插入默认) |
升级语法:
1 | db.集合名.update(条件,新数据) |
运算符 | 作用 |
---|---|
$inc | 递增 |
$netame | 重命名列 |
$set | 修改列值 |
$unset | 删除列 |
准备工作
1 | use test2; |
练习1:将{uname:"zs1"}改为{uname:"zs2"}
1 | > db.c3.update({uname:"zs1"},{uname:"zs2"}) |
发现: 默认不是修改,而是替换
解决:使用升级语法修改器需求: 使用修改器将zs2的姓名改为zs22
语法:db.c3.update({uname:"zs2"}, {$set: {uname: "zs22"}})
1
2
3
4
5
6
7
8
9
10
11
12
13
14 > db.c3.update({uname:"zs2"},{$set:{uname:"zs22"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c3.find()
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4f6"), "uname" : "zs22" }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4f7"), "uname" : "zs2", "age" : 2 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4f8"), "uname" : "zs3", "age" : 3 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4f9"), "uname" : "zs4", "age" : 4 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4fa"), "uname" : "zs5", "age" : 5 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4fb"), "uname" : "zs6", "age" : 6 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4fc"), "uname" : "zs7", "age" : 7 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4fd"), "uname" : "zs8", "age" : 8 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4fe"), "uname" : "zs9", "age" : 9 }
{ "_id" : ObjectId("5f3fd0a58989b2009f00b4ff"), "uname" : "zs10", "age" : 10 }
>发现默认只能改一条数据
练习2: 给{uname:"zs10"}的年龄加2岁或者减2岁
1 | > db.c3.find() |
练习3: 修改器综合练习
插入数据: db.c4.insert( {uname:"神龙教主",age:888,who:"男",other:"非国人"});
完成需求:
uname 改成 zykj (修改器: $set)
age 增加 111 (修改器: $inc)
who 改字段 sex (修改器: $netame)
other 删除 (修改器: $unset)语法|分析:
1
2
3
4
5
6
7
8
9
10
11
12
13 db.c4.update( {uname :"神龙教主"},{uname: "zykj"}) #错误, 替换
{$set: {uname: "zykj"}}
{$inc: {age: 111}}
{$netame: {who: "sex"}}
{$unset: {other: true}}
留心如何一次性写多个修改器
db.c4.update( {uname: "神龙教主"},{
$set: {uname : "zykj"},
$inc: {age: 111},
$netame: {who: "sex"},
$unset: {other: true}
})
示例:
1 | > db.c4.insert( {uname:"神龙教主",age:888,who:"男",other:"非国人"}) |
练习4: 验证语法最后两个参数(了解)
[验证]是否新增true是false否: 修改 uname 等于 zs30 的年龄 30岁
1 | > db.c3.find() |
[验证]是否修改多条true是, false否默认
1 | > db.c3.update({},{$set:{age:10}},false,false) |
删 D
语法: db.集合名.remove(条件[,是否删除一条])
注意: 是否删除一条true是,false否、默认为false
1 | > db.c3.find() |
小总结
增Create
1 | db.集合名.insert(JSON数据) |
删Delete
1 | db.集合名.remove(条件[是否删除一条true是false否默认]) |
改Update
1 | db.集合名.update(条件,新数据 [,是否新增,是否修改多条] ) |
查Read
1 | db.集合名.find(条件 [,查询的列]) |
教学管理系统数据库设计
图片中的字段:编号、学号、姓名、电话、性别、年龄、学历、备注
实战开发流程
数据库设计流程
根据UI设计稿
- 确定功能模块所属集合
- 确定集合字段
1 | UI设计稿每个展示内容对应一个字段 |
练习
- 需求:根据千锋教学系统,设置存放学生信息的集合,并插入20条测试数据
- 代码
1 | 1.先中文 |
示例:小知识: pretty() 可以格式化json字符串
1 | > use school |
排序&分页
明确需求
数据库,是用来存放数据的
咱们后期从数据库获取数据需要排序、多页展示如何实现?
准备
1 | use test3 |
排序
- 语法:
db.集合名.find().sort(JSON数据)
- 说明: 键-就是要排序的列/字段、值:
1升序 -1降序
- 练习:年龄升序&降序
1 | > use test3 |
Limit和Skip方法
语法:
db.集合名.find().sort().skip(数字).limit()
说明: skip跳过指定数量(可选),limit限制查询的数量
练习:1-降序查询查询2条,2-降序跳过2条并查询2条
1
2
3
4
5
6
7> db.c1.find().sort({age:-1}).skip(0).limit(2)
{ "_id" : 5, "name" : "d", "sex" : 2, "age" : 5 }
{ "_id" : 4, "name" : "c", "sex" : 2, "age" : 4 }
> db.c1.find().sort({age:-1}).skip(2).limit(2)
{ "_id" : 3, "name" : "b", "sex" : 2, "age" : 3 }
{ "_id" : 2, "name" : "a", "sex" : 1, "age" : 2 }
>
实战分页
需求:数据库1 -10数据,每页显示两条(5页)
语法: db.集合名.find().skip().limit(2)
1 | skip计算公式: (当前页 – 1) * 每页显示条数 |
小总结
db.集合名.find()
.sort({列:1/-1})
排序.skip(数字)
跳过指定数量.limit(数字)
限制查询条数.count()
统计总数量
聚合查询
明确需求
思考:如何统计数据、如何实现分组统计等?
回答: 通过MongoDB聚合查询
概念
聚合查询
顾名思义就是把数据聚起来,然后统计
语法
语法
1 | db.集合名称.aggregate([ |
常用管道
1 | $group 将集合中的文档分组,用于统计结果 |
常用表达式
1 | $sum 总和 $sum:1同count表示统计 |
准备
1 | use test4 |
练习
统计男生、女生总年龄
1
2
3
4
5
6
7
8db.c1.aggregate([
{
$group: {
_id: "$sex",
rs: {$sum:"$age"}
}
}
])示例:
1
2
3
4
5
6
7
8
9
10
11> db.c1.aggregate([
... {
... $group: {
... _id: "$sex",
... rs: {$sum:"$age"}
... }
... }
... ])
{ "_id" : 2, "rs" : 12 }
{ "_id" : 1, "rs" : 24 }
>统计男生、女生总人数
1
2
3
4
5
6
7
8db.c1.aggregate([
{
$group: {
_id: "$sex",
rs: {$sum:1}
}
}
])示例:
1
2
3
4
5
6
7
8
9
10
11> db.c1.aggregate([
... {
... $group: {
... _id: "$sex",
... rs: {$sum:1}
... }
... }
... ])
{ "_id" : 2, "rs" : 3 }
{ "_id" : 1, "rs" : 2 }
>求学生总数和平均年龄
1
2
3
4
5
6
7
8
9db.c1.aggregate([
{
$group:{
_id:null,
total_num:{$sum:1},
total_avg:{$avg:"$age"}
}
}
])示例:
1
2
3
4
5
6
7
8
9
10> db.c1.aggregate([
... {
... $group:{
... _id:null,
... total_num:{$sum:1},
... total_avg:{$avg:"$age"}
... }
... }
... ])
{ "_id" : null, "total_num" : 5, "total_avg" : 7.2 }查询男生、女生人数、按人数升序
1
2
3
4db.c1.aggregate([
{ $group: {_id:"$sex",rs:{$sum: 1}}},
{ $sort:{rs:1} }
])示例:
1
2
3
4
5
6
7> db.c1.aggregate([
... { $group: {_id:"$sex",rs:{$sum: 1}}},
... { $sort:{rs:1} }
... ])
{ "_id" : 1, "rs" : 2 }
{ "_id" : 2, "rs" : 3 }
>
优化索引
生活中的索引
公交路牌、字典的索引、办公区域索引
数据库中的索引
- 说明:索引是一种排序好的便于快速查询的数据结构
- 作用:帮助数据库高校的查询数据
索引优缺点
优点
提高数据查询的效率,降低数据库的IO成本
通过索引对数据进行排序,降低数据排序的成本,降低CPU的消耗缺点
占用磁盘空间
大量索引影响SQL语句效率,因为每次插入和修改数据都需要更新索引
语法
创建索引语法:
db.集合名.createlndex(待创建索引的列[,额外选项])
参数:
待创建索引的列:{键:1,….键:-1}
说明:1升序-1降序 例如{age:1}表示创建age索引并按照升序的方式存储
额外选项: 设置索引的名称或者唯一索引等等删除索引语法:
全部删除:
db.集合名.droplndexes()
删除指定:db.集合名.droplndex(索引名)
查看索引语法:
db.集合名.getlndexes()
练习
准备∶向数据库中新增十万条数据
1
2
3
4
5
6 //选择数据库
use test5;
//向数据库中添加数据
for(var i=0;i<100000;i++){
db.c1.insert({'name':"aaa"+i,"age":i});
}
创建普通索引:
需求: 给name添加普通索引
练习1: 给name添加普通索引,命令:
db.c1.createIndex({name:1})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 > db.c1.count()
100000
> db.c1.createIndex({name:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.c1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "name_1"
}
]
>练习2: 删除name索引,命令:
db.c1.dropIndex('name_1')
1
2
3
4
5 > db.c1.dropIndex('name_1')
{ "nIndexesWas" : 2, "ok" : 1 }
> db.c1.getIndexes()
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
>练习3: 给name创建索引并起名zykj
命令:
db.c1.createIndex({name:1},{name:"zykj"})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 > db.c1.createIndex({name:1},{name:"zykj"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.c1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "zykj"
}
]
>
创建符合索引
需求:给name和age添加组合索引
说明:就是一次给两个字段建立索引
语法:
db.集合名.createIndex({键1:方式,键2:方式})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 > db.c1.createIndex({name:1,age:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
> db.c1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "zykj"
},
{
"v" : 2,
"key" : {
"name" : 1,
"age" : 1
},
"name" : "name_1_age_1"
}
]
>
创建唯一索引
需求:给 name 添加普通索引
语法:
db.集合名.createIndex(待添加索引的列,{unique:列名})
练习1:删除全部索引,命令:
db.c1.dropIndexes()
1
2
3
4
5
6
7
8
9 > db.c1.dropIndexes()
{
"nIndexesWas" : 3,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.c1.getIndexes()
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
>练习2:设置唯一索引、命令:
db.createIndex({name:1},{unique:"name"})
1
2
3
4
5
6
7
8 > db.c1.createIndex({name:1},{unique:"name"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>练习3:测试唯一索引的特性,
命令:
db.c1.insert({name:"a"}) db.c1.insert({name:"a"})
1
2
3
4
5
6
7
8
9
10
11
12 > db.c1.insert({name:"a"})
WriteResult({ "nInserted" : 1 })
> db.c1.insert({name:"a"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test5.c1 index: name_1 dup key: { name: \"a\" }"
}
})
>
分析索引(explain)
语法: db.集合名.find().explain('executionStats')
说明:
COLLSCAN
全表扫描IXSCAN
索引扫描FETCH
根据索引去检索指定document
练习
测试: age未添加索引情况
语法:db.c1.find({age:18}).explain('executionStats');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 > db.c1.find({age:18}).explain('executionStats')
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test5.c1",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$eq" : 18
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$eq" : 18
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 121,
"totalKeysExamined" : 0,
"totalDocsExamined" : 100001,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$eq" : 18
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 7,
"works" : 100003,
"advanced" : 1,
"needTime" : 100001,
"needYield" : 0,
"saveState" : 100,
"restoreState" : 100,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 100001
}
},
"serverInfo" : {
"host" : "MACHENIKE-SRTYLP00",
"port" : 27017,
"version" : "4.4.0",
"gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
},
"ok" : 1
}
>测试:age 未添加索引情况
语法:db.c1.find({age:18}).explain ('executionStats');
测试:age 添加索引情况
语法:db.c1.createIndex ({age: 1})
继续:db.c1.find({age:18}).explain('executionStats')
选择规则(如何选择合适的列创建索引)
- 为常做条件、排序、分组、联合操作的字段建立索引
- 选择唯—性索引(ps.同值较少如性别字段)
- 选择较小的数据列,为较长的字符串使用前缀索引(ps.索引文件更小)
权限机制
明确需求
发现我们再DOS窗口直接输入命令就可以登录数据库
这在实战工作中绝对不允许的
思考:如何解决
回答: 使用权限机制,开启验证模式即可
语法
1 | db.createUser({ |
角色种类 | 说明 |
---|---|
超级用户角色 | root |
数据库用户角色 | read 、readWrite |
数据库管理角色 | dbAdmin 、userAdmin |
集群管理角色 | clusterAdmin 、clusterManager 、clusterMonitor 、hostManager |
备份恢复角色 | backup 、restore |
所有数据库角色 | readAnyDatabase 、readWriteAnyDatabase 、userAdminAnyDatabase 、dbAdminAnyDatabase |
角色 | 角色说明 |
---|---|
root | 只在 admin 数据库中可用。超级账号,超级权限; |
read | 允许用户读取指定数据库 |
readWrite | 允许用户读写指定数据库 |
dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问 system.profile; |
dbAdminAnyDatabase | 只在 admin 数据库中可用,赋予用户所有数据库的 dbAdmin 权限 |
clusterAdmin | 只在 admin 数据库中可用,赋予用户所有分片和复制集相关函数的管理权限 |
userAdmin | 允许用户向 system.users 集合写入,可以找指定数据库里创建、删除和管理用户 |
userAdminAnyDatabase | 只在 admin 数据库中可用,赋予用户所有数据库的 userAdmin 权限 |
readAnyDatabase | 只在 admin 数据库中可用,赋予用户所有数据库的读权限 |
readWriteAnyDatabase | 只在 admin 数据库中可用,赋予用户所有数据库的读写权限 |
开启验证模式
开启验证模式概念: 名词,指用户需要输入账号密码才能登陆使用
操作步骤
- 添加超级管理员
- 退出卸载服务
- 重新安装需要输入账号密码的服务(注在原安装命令基础上加上–auth即可
- 启动服务->登陆测试
步骤1∶添加超级管理员
1 | mongo |
脚下留心:2.x3.x4.x前面版本默认是看不到admin没关系你直接选中即可
示例:
1 | > db.createUser({ |
步骤2: 退出卸载服务
脚下留心: DOS窗口必须用管理员省份运行
1 | bin\mongod --remove |
示例:
1 | D:\Programs\MongoDB\bin>mongod --remove |
步骤3∶安装需要身份验证的MongoDB服务
在原安装命令基础上加 --auth
1 | mongod --install --dbpath D:\Programs\MongoDB\data --logpath D:\Programs\MongoDB\logs\mongoDB2.log --auth |
示例:
1 | D:\Programs\MongoDB\bin>mongod --install --dbpath D:\Programs\MongoDB\data --logpath D:\Programs\MongoDB\logs\mongoDB2.log --auth |
通过超级管理员账号登录
方法1:
mongo服务器IP地址:端口/数据库 -u 用户名 -p 密码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26D:\Programs\MongoDB\bin>mongo localhost:270107/admin -u admin -p 123456
MongoDB shell version v4.4.0
exception: Port number 270107 out of range parsing HostAndPort from "localhost:270107"
exiting with code 1
D:\Programs\MongoDB\bin>mongo localhost:27017/admin -u admin -p 123456
MongoDB shell version v4.4.0
connecting to: mongodb://localhost:27017/admin?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("05f0c834-a11b-42e7-af35-eafddd17cf95") }
MongoDB server version: 4.4.0
---
The server generated these startup warnings when booting:
2020-08-22T21:56:41.558+08:00: This server is bound to localhost. Remote systems will be unable to connect to this server. Start the server with --bind_ip <address> to specify which IP addresses it should serve responses from, or with --bind_ip_all to bind to all interfaces. If this behavior is desired, start the server with --bind_ip 127.0.0.1 to disable this warning
---
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
>方法2:
a-先登录,b-选择数据库,c-输入db.auth(用户名,密码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19D:\Programs\MongoDB\bin>mongo
MongoDB shell version v4.4.0
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a3cc854e-96aa-445e-9824-5514ef382981") }
MongoDB server version: 4.4.0
> use admin
switched to db admin
> db.auth('admin','123456')
1
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
school 0.000GB
test2 0.000GB
test3 0.000GB
test4 0.000GB
test5 0.004GB
>
练习
需求
添加用户shop1可以读shop数据库
添加用户shop2可以读写shop数据库
脚下留心: 必须在对应数据库创建用户准备: 创建测试数据和测试用户(注:选择shop仓库创建用户)
1
2
3
4use shop;
for(var i=1; i<=10; i++) {
db.goods .insert({ "name" : "goodsName"+i , "price" :i});
}添加用户并设置权限
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 切记
use shop
// shop1 只能读
db.createUser({
"user" : "shop1",
"pwd": "shop1",
"roles" : [{
role: "read",
db: "shop"
}]
})
// shop2 只能写
db.createUser({
"user" : "shop2",
"pwd": "shop2",
"roles" : [{
role: "readWrite",
db: "shop"
}]
})验证
1
2
3mongo localhost:270107/shop -u shop1 -p shop1
mongo localhost:270107/shop -u shop2 -p shop2
备份还原
明确需求
在实战工作中一定要做好数据库备份工作
否则万一数据丢失
带来的影响是巨大的
不知道为啥下面的命令我执行不了。。。
备份数据库mongodump
1 | mongodump -h -port -u -p -d -o |
-h
表示服务器 IP 地址(不写默认本机)-port
表示端口(默认 27017)-u
表示账号-p
表示密码-d
表示数据库(数据库不写则导出全部)-o
备份到指定目录下
练习(备份所有数据):
mongodump -u admin -p 123456 -o D:\Programs\MongoDB\bak
练习(备份指定数据):
mongodump -u shop2 -p shop2 -d shop -o D:\Programs\MongoDB\bak
还原数据库mongorestore
1 | mongorestore -h -port -u -p --drop -d |
-h
表示服务器 IP 地址(不写默认本机)-port
表示端口(默认 27017)-u
表示账号-p
表示密码-d
表示数据库(数据库不写则还原所有)–drop
表示先删除在导出,不写则覆盖
还原所有数据
1
mongorestore -u admin -p 123456 --drop D:\Programs\MongoDB\back
备份指定数据库
1
mongorestore -u shop2 -p shop2 -d shop --drop D:\Programs\MongoDB\back1\shop
实战可视化管理工具
简介
adminMongo WEB/PC端口网页管理 https://adminmongo.markmoffat.com/
Robo 3T * 客户端软件 https://robomongo.org/download/
MongoVUE 客户端软件
Navicat 客户端软件 (同样推荐使用)
安装Robo 3T
安装步骤省略