MongoDB数据库从初级到高级【创作不易,还望喜欢的同志们能够一键三连呀!】
一、MongoDB安装
主要讲一下Windows安装
二、MongoDB基本操作
# 基本概念
生活中:仓库、架子、物品
计算机:数据库(database)、集合(collection)、数据\文档(document)
# 查看数据库
语法:show databases
效果:
# 选择数据库
语法:use 数据库名
效果:
隐式创建:在mongodb选择不存在的数据库不会报错,后期当该数据库有数据时,系统自动创建。
# 查看集合
语法:show collections
效果:
# 创建集合
语法:db.createCollection('集合名‘)
效果:
# 删除集合
语法:db.集合名.drop()
效果:
思考:mongdb如何删除数据库?
回答:学会自己百度:
st1:通过use语法选中数据库,
st2:通过db.dropDatabase()删除数据库
# 小总结
数据库(查看、创建、选择、删除
查看:show databases
创建:有单独的语法,但是忽略 隐式创建
选择:use 数据库名
删除:1通过use选中数据库,2通过db.dropDatabse()删除数据库
集合(查看、创建、删除
查看:show collections
创建:db.createCollection('集合名’)
删除:db.集合名.drop()
三、MongoDB文档增删修查(CURD)
明确需求
数据库主要用于存放项目数据
思考:如何实现集合中数据的增删改查呢?
回答:通过MongoDB语法即可
# C增
语法:db.集合名.insert(JSON数据)
说明:集合存在-则直接插入数据;集合不存在-隐式创建
练习:在test2数据库的c1集合中插入数据(姓名叫webopenfather年龄18岁)
use test2
db.c1.insert({uname:“webopenfather”, age:19})留心1:数据库和集合不存在都隐式创建
留心2:对象的键统一不加引号方便看,但是查看集合数据时系统会自动加
留心3:MongoDB会给每条数据增加一个全球唯一的_id键
- 思考1:是否可以自定义_id值?
回答:可以,只需要给插入的JSON数据增加_id键即可覆盖(实战强烈不推荐)
- 思考2:如何一次性插入多条记录?
回答:传递数据,数组中写一个个JSON数据即可
db.c1.insert([
{uname:"z3", age:3},
{uname:"l4", age:3},
{uname:"w5", age:3},
])
含义:一次性插入3条数据到c1集合
- 思考3:如何快速插入10条数据
回答:mongodb底层使用JS引擎实现,所以支持部分JS语法
因此:可以写for循环
use test2
for (var i=1; i<=10; i++){
db.c2.insert({uname: "a"+1, age: i})
}
# R查
基础语法:db.集合名.find(条件 [,查询的列])
条件:
查询所有数据 :{}或者不写
查询age=6的数据:{age:6}
既要age=6又要性别=男 :{age:6,sex=‘男’}
查询的列(可选参数
不写 - 这查询全部列(字段
{age:1} - 只显示age列(字段
{age:0} - 除了age列(字段都显示
留心:不管你怎么写系统自定义的_id都会在
升级语法
db.集合名.find({键:值}) 注:值不直接写
{运算符:值}
db.集合名.find({
键:{运算符:值}
})
运算符 | 作用 |
---|---|
$gt | 大于 |
$gte | 大于等于 |
$lt | 小于 |
$lte | 小于等于 |
$ne | 不等于 |
$in | in |
$nin | not in |
- 练习1:查询所有数据
- 练习2:查询年龄大于5岁的数据?
- 练习3:只看年龄为5,8,10的数据?
# U改
基础语法:db.集合名.update (条件, 新数据[,是否新增,是否修改多条])
是否新增:指条件匹配不到数据则插入(true是插入,false否不插入默认)
是否修改多条:指将匹配成功的数据都修改(true是,false否默认)
升级语法
db.集合名.update (条件, 新数据)
{修改器:{键:值}}
运算符 | 作用 |
---|---|
$inc | 递增 |
$rename | 重命名列 |
$set | 修改列值 |
$unset | 删除列 |
准备工作
use test2
for (var i = 1; i <= 10; i++){
db.c3.insert( {"uname":"zs"+i,"age":i});
}
- 练习1:将{uname:“zs1”}改为{uname:“zs2”}
发现:默认替换,而不是修改
解决:使用升级语法 修改器
需求:使用修改器将zs3的姓名改为zs33
语法:db.c3.update({uname:“zs3”}, {$set:{uname: “zs33”}})
- 练习2:给{uname:“zs10”}的年龄加2岁或者减2岁
- 练习3:修改器综合练习
插入数据:db.c4.insert({uname:“神龙教主”,age:888,who:“男”,other:“非国人”});
完成需求:
uname 改成 神龙教主 (修改器: s e t ) a g e 增 加 111 ( 修 改 器 : set) age 增加 111 (修改器: set)age增加111(修改器:inc)
who 改字段 sex (修改器: r e n a m e ) o t h e r 删 除 ( 修 改 器 : rename) other 删除 (修改器: rename)other删除(修改器:unset)
语法分析:
db.c4.update({uname:"神龙教主"}, {uname: "webopenfather"}) #错误,替换
{$set: {uname: "webopenfather"}}
{$inc: {age: 111}}
{$rename: {who: "sex"}}
{$unset: {other: true}}
留心如何一次性写多个修改器
db.c4.update({uname:"神龙教主"}, {
$set: {uname: "webopenfather"},
$inc: {age: 111},
$rename: {who: "sex"},
$unset: {other: true}
})
- 练习4:验证语法最后两个参数(了解)
【验证】是否新增true是false否:修改uname 等于 zs30的年龄 30岁
【验证】是否修改多条true是,false否默认
# D删
语法:db.集合名.remove(条件 [,是否删除一条])
注意:是否删除一条true是,false否 默认
#小总结
高级开发工程师统称:所有数据库都需要增删改查CURD标识
MongoDB删除语法:remove
- 增Create
db.集合名.insert(JSON数据)
- 删Delete
db.集合名.remove(条件 [,是否删除一条true是false否默认])
也就是默认删除多条
- 改Update
db.集合名.update(条件, 新数据 [,是否新增,是否修改多条])
升级语法db.集合名.update(条件, {修改器:{键:值}})
- 查Read
db.集合名.find(条件 [,查询的列])
注:实战教学管理系统数据库设计
1.实战开发流程
2.数据库设计流程
根据UI设计稿
1.确定功能模块所属集合
2.确定集合字段
UI设计稿每个展示内容对应一个字段
创建于字段
更新于字段
状态字段
最后:先中文、再英文
留心:后期肌肉记忆,下意识直接创建
3.练习
- 需求:根据教学系统,设置存放学生信息的集合,并插入20条测试数据
- 代码:
1.先中文
集合名词:学生集合
集合字段:编号、学号、姓名、电话、性别、年龄、学历、备注
2.再英文
use school
for (var num=1; num<=20; num++){
db.stu.insert({
id:num,
no:"QF"+num,
uname:"神龙教"+num,
tell:"11111111",
sex:"女",
age:num,
school:"研究生",
remark:"土豪"
})
}
四、MongoDB排序&分页
明确需求
数据库,是用来存放数据的
准备
use test3
db.c1.insert({_id:1,name:"a",sex:1,age:1})
db.c1.insert({_id:2,name:"a",sex:1,age:2})
db.c1.insert({_id:3,name:"b",sex:2,age:3})
db.c1.insert({_id:4,name:"c",sex:2,age:4})
db.c1.insert({_id:5,name:"d",sex:2,age:5})
db.c1.find()
排序
语法:db.集合名.find().sort(JSON数据)
说明:键-就是要排序的列/字段、值:1升序、-1降序
练习:年龄升序&降序
Limit与Skip方法
语法:db.集合名.find().sort().skip(数字).limit(数字)
说明:skip跳过指定数量(可选),limit限制查询数量
练习:1.降序查询查询2条,2.降序跳过2条并查询2条
实战分页
- 需求:数据库1-10数据,每页显示两条(5页)
- 语法:db.集合名.find().skip().limit(2)
skip计算公式:(当前页 - 1)* 每页显示条数
1页 1 2 skip0
2页 3 4 skip2
3页 5 6 skip4
4页 7 8 skip6
5页 9 10 skip8
# 小总结
db.集合名.find()
.sort({列:1/-1})排序
.skip(数字) 跳过指定数量
.limit(数字) 限制查询条数
.count() 统计总数量
不够: 百度或谷歌
五、MongoDB聚合查询
明确需求
- 思考:如何统计数据、如何实现分组统计等?
- 回答:通过MongoDB聚合查询
概念
聚合查询
顾名思义就是把数据聚起来,然后统计
语法
语法
db.集合名词.aggregate([
{管道:{表达式}}
...
])
常用管道
$group 将集合中的文档分组,用于统计结果
$match 过滤数据,只要输出符合条件的文档
$sort 聚合数据进一步排序
$skip 跳过指定文档数
$limit 限制集合数据返回文档数
...
常用表达式
$sum 总和 $sum:1同count表示统计
$avg 平均
$min 最小值
$max 最大值
...
准备
use test4
db.c1.insert({_id:1,name:"a",sex:1,age:1})
db.c1.insert({_id:2,name:"a",sex:1,age:2})
db.c1.insert({_id:3,name:"b",sex:2,age:3})
db.c1.insert({_id:4,name:"c",sex:2,age:4})
db.c1.insert({_id:5,name:"d",sex:2,age:5})
练习
统计男生、女生的总年龄
db.c1.aggregate([
{
$group:{
_id:"$sex",
rs:{$sum: "$age"}
}
}
])
统计男生、女生的总人数
db.c1.aggregate([
{
$group:{
_id:"$sex",
rs:{$sum: 1}
}
}
])
求学生总数和平均年龄
db.c1.aggregate([
{
$group:{
_id: null,
total_num: {$sum:1},
total_avg: {$avg: "$age"}
}
}
])
查询男生、女生人数,按人数升序
db.c1.aggregate([
{$group:{_id:"$sex",rs: {$sum: 1}}},
{$sort:{rs: 1}}
])
六、MongoDB优化索引
生活中的索引
数据库中的索引
- 说明:索引是一种排序好的便于快速查询的数据结构
- 作用:帮助数据库高效地查询结果
索引优缺点
- 优点
提高数据查询的效率,降低数据库的IO成本
通过索引对数据进行排序,降低数据排序的成本,降低CPU的消耗
- 缺点
占用磁盘空间
大量索引影响SQL语句效率,因为每次插入和修改数据都需要更新索引
语法
- 创建索引语法:db.集合名.createIndex(待创建索引的列 [,额外选项])
- 参数:
待创建索引的列:{键:1,…,键:-1}
说明:1升序 -1降序 例如{age:1}表示创建age索引并按照升序的方式存储
额外选项:设置索引的名称或者唯一索引等等
- 删除索引语法:
全部删除:db.集合名.dropIndexes()
删除指定:db.集合名.dropIndex(索引名)
- 查看索引语法:db.集合名.getIndexes()
练习
准备:向数据库中新增十万条数据
//选择数据库
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})
练习2:删除name索引,命令:db.c1.dropIndex(‘name_1’)
练习3:给name创建索引并起名webopenfather
命令:db.c1.createIndex({name:1},{name:“webopenfather”})
创建复合/组合索引
需求:给name和age添加组合索引
说明:就是一次性给两个字段建立索引
语法:db.集合名.createIndex({键1:方式,键2:方式})
创建唯一索引
需求:给name添加普通索引
语法:db.集合名.createIndex(待添加索引的列,{unique:列名})
练习1:删除全部索引,命令:db.data1.dropIndexes();
练习2:设置唯一索引,命令:db.c1.createIndex({name:1},{unique:“name”})
练习3:测试唯一索引特性
命令:
db.c1.insert({name:“a”});
db.c1.insert({name:“a”});
分析索引(explain)
- 语法:db.集合名.find().explain(‘executionStats’)
- 说明:
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索指定document
- 练习
测试:age未添加索引情况
语法:db.c1.find({age:18}).explain(‘executionStats’);
测试:age添加索引情况
语法:db.c1.createIndex({age:1})
继续:db.c1.find({age:18}).explain(‘executionStats’);
选择规则(如何选择合适的列创建索引)
- 为常做条件、排序、分组的字段建立索引
- 选择唯一性索引 (ps:同值较少如性别字段)
- 选择较小的数据列,为较长的字符串使用前缀索引 (ps:索引文件更小)
七、MongoDB权限机制
明确需求
发现我们在DOS窗口直接输入命令就可以登录数据库
但是在实战中绝对不允许的
思考:如何解决
回答:使用权限机制,开启验证模式即可
语法
创建账号
db.createUser({
"user" : "账号",
"pwd" : "密码",
"roles" :[{
role: "角色"
db: "所属数据库"
})
})
角色
开启验证模式
开启验证模式概念:名词,指用户需要输入账号密码才能登陆使用
- 操作步骤
- 添加超级管理员
- 退出卸载服务
- 重新安装需要输入账号密码的服务(注在原安装命令基础上加上–auth即可)
- 启动服务 -> 登陆测试
八、MongoDB备份还原
明确需求
备份数据库mongodump
还原数据库mongorestore
九、mongoose简介
明确需求
为什么学数据库,因为要存放项目/网站数据
- 思考:实战中也像我们之前那样敲命令吗?
回答:非也,通过程序来进行 - 思考:如何实现?
回答:mongoose
是什么
是node中提供操作MongoDB的模块
能干什么
能够通过node语法实现MongoDB数据库增删改查
从而实现node写程序来管理MongoDB数据库
去哪儿下
npm i mongoose
或者
yarn add mongoose
schema
作用:用来约束MongoDB文档数据(哪些字段可以,