文章目录

  • MongoDB实战教学管理系统数据库设计
  • 实战开发流程
  • 数据库设计流程
  • 练习
  • MongoDB排序&分页
  • 明确需求
  • 准备
  • 排序
  • Limit与Skip方法
  • 实战分页
  • 小总结
  • MongoDB聚合查询
  • 明确需求
  • 概念
  • 语法(略复杂)
  • 准备
  • 练习
  • MongoDB优化索引
  • 数据库中的索引
  • 索引优缺点
  • 语法
  • 练习
  • 分析索引(explain)
  • 选择原则 (如何选择合适的列创建索引)
  • MongoDB权限机制
  • 明确需求
  • 语法(略难)
  • 开启验证模式
  • 通过超级管理员账号登陆
  • 练习
  • MongoDB备份还原
  • 明确需求
  • 备份数据库mongodump
  • 还原数据库mongorestore
  • 实战可视化管理工具
  • 简介
  • 明确需求
  • 是什么
  • 能干嘛
  • 去哪下
  • schema
  • model
  • 小总结
  • mongoose使用
  • 安装
  • 语法
  • 接口概念
  • 明确需求
  • 什么是
  • 就是一个文件(js\json\php等,主要响应JSON数据 (操作方便,体积小)或XML数据 { status : 1/0, msg: '提示信息' }
  • 能干嘛
  • 去哪下(找)
  • 小总结
  • 接口开发规范 (Restful API)
  • 明确需求
  • 是什么&好处
  • 标准的RESTful架构/思想/规则需要做到
  • 小总结
  • 实战教学管理系统学生模块接口开发
  • express简介



MongoDB实战教学管理系统数据库设计

实战开发流程

数据库设计流程

根据UI设计稿
1确定功能模块所属集合
2确定集合字段
UI设计稿每个展示内容对应一个字段
创建于字段
更新于字段
状态字段

最后:先中文,再英文
留心:上述规则照顾基础差的,如果大神 或 久而久之 就变成肌肉记忆 下意识直接创建

练习

● 需求:根据教学系统,设置存放学生信息的集合,并插入20条插入数据
● 代码
1.先中文
集合名称:学生集合
集合字段:编号,学号,姓名,电话、性别、年龄、学历、备注

2.再英文
这个代码可以更清晰的看清楚数据 db.stu.find().pretty()

use school
 for ( var num =1 ; num<=20; num++) {
 db.stu.insert({
 id:num,
 no: “QF”+num,
 uname: “神龙教”+num,
 tel: “1111111111”,
 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 0
2页 3 4 2
3页 5 6 4
4页 7 8 6
5页 9 10 8

小总结

db.集合名.find()
.sort({列:1/-1} ) 排序
.skip(数字) 跳过指定数量
.limit(数字)限制查询条数
.count() 统计总数量
不够:百度或谷歌

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([
{
KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{ _id: "sex",
rs: { $ sum: “$age” }
}
}
])

● 统计男生、女生的总人数
db.c1.aggregate( [
{
KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{ _id: "sex",
rs: { $ sum: 1}
}
}
])

● 求学生总数和平均年龄
db.c1.aggregate( [
{
KaTeX parse error: Expected '}', got 'EOF' at end of input: …l, total_num: {sum:1},
total_avg: {mongodb 字段中的字段排序_数据age"}
}
}
])

● 查询男生、女生人数、按人数升序
db.c1.aggregate( [
{ KaTeX parse error: Expected '}', got 'EOF' at end of input: 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添加普通1索引,命令: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.data1.insert({name:“a”});
db.data1.insert({name:“a”});

分析索引(explain)

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权限机制

明确需求

发现我们在BOS窗口直接输入命令就可以登录数据库
这在实战工作中绝对不允许的
思考:如何解决
回答:使用权限机制,开启验证模式即可

语法(略难)

创建账号
db.createUser({
“user”:“账号”,
“pwd”:“密码”,
“roles”:[{
role:“角色”,
db:“所属数据库”
}]
})
角色
#角色种类
超级用户角色:root
数据库用户角色: read、readwrite;
数据库管理角色:dbAdmin、userAdmin;
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
备份恢复角色:backup、restore;
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、
dbAdminAnyDatabase

#角色说明
root:只在admin数据库中可用。超级账号,超级权限;
read:允许用户读取指定数据库;
readWrite:允许用户读写指定数据库;

开启验证模式

开启验证模式概念:名词,指用户需要输入账号密码才能登录使用
操作步骤

  1. 添加超级管理员
  2. 退出卸载服务
  3. 重新安装需要输入账号密码的服务(注在原安装命令基础上加上)–auth 即可
  4. 启动服务 ->登录测试

步骤1:添加超级管理员

mongo
use admin
 db.createUser({
 “user” : “admin”,
 “pwd” : “admin888”,
 “roles” : [ {
 role : “root”,
 db : “admin”
 }]
 })


脚下留心:2.x 3.x 4.x 前面版本默认是看不到admin没关系 你直接选中即可
步骤2:退出卸载服务
bin\mongod --remove

脚下留心:DOS窗口必须用管理员身份运行
步骤3:安装需要身份验证的MongoDB服务
bin\mongod --install --dbpath E:\mongodb\data --logpath
E:\mongodb\logs\mongodb2.log --auth

步骤4:启动服务 ->登录测试

通过超级管理员账号登陆

● 方法1:mongo 服务器IP地址:端口/数据库 -u 用户名 -P 密码


● 方法2:a-先登录 ,b-选择数据库,c-输入db.auth(用户名,密码)

练习

● 需求
添加用户shop1可以读shop数据库
添加用户shop2可以读写shop数据库
脚下留心:必须在对应数据库创建用户
● 准备:创建测试数据和测试用户 (注:选择shop仓库创建用户)
use shop;
for(var i =1; i<=10; i++) {
db.goods.insert({“name”: “goodsName”+i, “price”:i});
}
● 添加用户并设置权限

##切记
 use shop//shop1
 db.createUser({
 “user” : “shop1”,
 “pwd” : “admin888”,
 “roles” : [{
 role: “read”,
 db : “shop”
 }]
 })//shop2
 db.createUser({
 “user” : “shop2”,
 “pwd” : “admin888”,
 “roles” : [{
 role: “readWrite”,
 db : “shop”
 }]
 })


● 验证:shop1可读

● 验证:shop2验证可读可写

MongoDB备份还原

明确需求

在实战工作中一定要做好数据库备份工作
否则万一数据丢失
带来的影响是巨大的

备份数据库mongodump

● 语法
导出数据语法:mongodump -h -prot -u -p -d -o
导出语法说明
-h host 服务器IP地址 (一般不写 默认本机)
-port 端口 (一般不写 默认27017)
-u user 账号
-p pwd 密码
-d database 数据库 (留心:数据库不写则导出全局)
-o open 备份到指定目录下
● 练习(备份所有数据): mongodump -u admin -p admin888 -o E:\mongodb\bak

● 练习(备份指定数据): mongodump -u admin -p admin888 -d shop -o E:\mongodb\bak2

还原数据库mongorestore

● 语法:
还原数据语法:mongorestore -h -port -u -p -d --drop 备份数据目录
还原数据说明:
-h
-port
-u
-p
-d 不写则还原全部数据
–drop 先删除数据库再导入

● 练习:还原所有数据:mongorestore -u admin -p admin888 --drop E:\mongodb\bak




● 练习(还原指定数据):mongorestore -u shop2 -p admin888 -d shop --drop E:\mongodb\bak2\shop

实战可视化管理工具

简介

Robo 3T* 客户端软件 https://robomongo.org/download/
mongoose简介

明确需求

为什么学数据库,因为要存放项目/网站数据
思考:实战中也像我们刚刚那样敲命令
回答:非也,而是通过程序来
思考:如何实现呢?
回答: mongoose

是什么

是node中提供操作MongoDB的模块

能干嘛

能够通过node语法实现MongoDB数据库增删改查
从而实现用node写程序来管理MongoDB数据库

去哪下

npm i mongoose
或者
yarn add mongoose (推荐

schema

英文网:https://mongoosejs.com
中文网:https://mongoosejs.net/
作用:用来约束MongoDB文档数据 (哪些字段必须,哪些字段可选的)

model

一个模型 对应 一个集合
后面我们通过模型来管理集合中的数据

小总结

为什么要学习mongoose: 通过命令管理mongodb麻烦,通过程序管理
是什么:就是node的一个模块
能干嘛:让node借助这个模块实现管理mongodb的程序
去哪下; 通过npm或yarn命令来安装
mongoose核心概念
schema 约束字段/列数据
model模型 对应 集合 后期用它来实现数据增删改查

mongoose使用

安装

步骤1:创建api目录
步骤2:在api目录下安装mongoose模块

语法

// 一,导入模块
 const mongoose =require(‘mongoose’);
 // 二,连接数据库
 const db =mongoose.createConnection(‘mongodb://user:pass@localhost:port/database’,
 {useNewUrl Parser: true, useUnifiedTopology: true }, err=>{
 if(err) {
 console.log(‘--------------------------------’)
 console.log(‘数据库连接失败:’,err)
 console.log(‘--------------------------------’)
 return;
 }
 console.log(‘数据库连接成功’);
 })
 // 三,设置数据模型 (声明是哪个集合,限制字段个数和字段类型)
 const model =db.model(‘user’, {
 name:{type:String, default:“username”},
 age:{type: Number },
 sex:{ type:String}
 })
 // 四. 创建实列操作(CURD)// 增 --------------------------------------------------
 const insertobj = new model (数据对象)
 方法1:insertobj.save((err) => db.close())
 方法2:(推荐)
 insertobj.save()
 .then(res=>{
 return res
 })
 .catch(err => {
 console.log(‘插入失败’ +err )
 return false
 })
 r.jsrPage.js 排序 分页
// 删 -------------------------------------------------------------
 方法1:model.remove/deleteone/deleteMany(条件对象, (err) => db.close() )
 方法2:(推荐)
 model.deleteone(条件对象)
 .then(res => {
 return res.deletedCount
 })// 查 ----------------------------------------------------------------------------------------
 方法1:model.find/findOne(条件对象, 要显示的字段数据对象,(err, result) => db.close() )
 方法2(推荐)
 model.findOne(条件对象)
 .then(res => {
 return res
 })
 .catch(err => {
 console.log(err)
 return false
 })

接口概念

明确需求

随着移动互联网的发展,客户端层出不穷,微信端,WEB/PC, APP等等,而后端业务逻辑基本是一致的,如何做到业务逻辑 一次编写,随时接入 呢

什么是

就是一个文件(js\json\php等,主要响应JSON数据 (操作方便,体积小)或XML数据

{
 status : 1/0,
 msg: ‘提示信息’
 }

1/0 提示信息 ● 多学一招: 只要响应JSON数据所有语言都可以操作, 列如ios/Android等 ● 推荐 { meta: { msg: 提示信息, status: 状态码 (200/201/301/302/400/401/403/404/500) }, data:数据 }

能干嘛

数据角度:让我们的项目静态/固定数据动态 (也就是让项目数据来源于数据库)
功能角度:短信接口,幽默笑话接口,天气接口,股票接口等

去哪下(找)

● 方案1:通过node/go/java/php/asp等语言去开发
● 方法2:使用第三方接口

小总结

为什么要有接口:一次编写,多次/随时接入 (好处:减少后端工作量方便后期维护)
什么是接口:就是一个文件,但是你必须返回json或xml数据
接口能干嘛:1-数据角度:页面数据动态,2-功能角度:短信接口,人脸识别接口
去哪下:1-自己写,2-去第三方网站找

接口开发规范 (Restful API)

明确需求

思考:接口可能是一个人开发,也可能多人开发,如何保证大家的编写规范一样
商品模块 /goods/getIndex get
订单模块 /order/index post
用户模块 /user
发现:上述这种case项目没有统一开发规则
问题:后期维护麻烦
回答:通过目前比较火的Restful API思想/架构

是什么&好处

● 说明:RESTful是目前最流行的一种互联网软件架构 (思想)
● 作用:声明/提供了接口设计原则和约束条件 (一个范围)
● 相关:
后端将资源发布到URL上->前端通过URL访问资源->并通过HTTP动词表示要对资源进行的操作
后端定义接口->前端请求接口=>HTTP动词表明操作目的 (get获取post新建put更新等)
● 举粟
列表页:访问-/模块名 (get)
详情页:访问-/模块名/编号 (get)
添加页:访问-/模块名create (get)
处理:访问 - /模块名 (get)
修改页: 访问 -模块页 /编号/edit (get)
处理:访问 -/模块名 /编号 (put)
删除:访问 - /模块名/编号 (delete)

HTTP动词:get , post , put , delete
● 好处:统一开发规范,便与团队协作开发

标准的RESTful架构/思想/规则需要做到

订单模块
/order get
/order post
/order /编号 put
/order / 编号 delete

● 项目所有模块有统一的标准
● 看URL就知道要操作的资源是什么(也就是哪儿个模块)
● 看Http Method就知道操作动作是什么,是添加 (post)还是删除 (delete)
● 看Http Status Code 就知道操作结果如何,是成功 (200) 还是内部错误 (500)

小总结

什么是restful api:是一个架构或思想
作用:声明了接口设计原则和约束条件
好处:统一开发规范,便于团队合作
接口测试工具 (Postman&insomnia)
方式

实战教学管理系统学生模块接口开发

express简介

● 是什么:基于Nodejs开发的一个框架 (原理基于node内置http模块封装)
● 好 处:加快项目开发,便于团队协作
学生添加接口
步骤1:定义路由 /stu post
步骤2:响应任意json数据
步骤3:定义stu模块,定义创建数据的方法
步骤4:调用stu模型创建数据的方法,返回结果
学生列表接口
学生列表接口分页