node-js 学习笔记
node-js 学习笔记
day01
一
1安装完之后node--js之后检查
2 五大浏览器:ie 谷歌 火狐 safri opera 内核:渲染引擎(css+html)+js引擎
3.cmd常用命令
ping:检查连接
ipconfig:当前ip地址
ctrl+c 退出前一步的环境
cd 前进或后退文件夹
dir 查看当前路径下的所有文件夹
tab 根据名字补全文件名
cls 清除cmd窗口下的已打印指令
上翻/下翻 找到之前/之后输入的指令
4 学习node-js
1个中心思想--模块化开发
2个关键词--module exports require
export default import
3种分类 自带模块 第三方模块 自定义模块
二 es6模块化开发语法
1 用sc来引入数据,数据不安全 曝露在全局
2 模块化环境 只有当前环境能用,更安全 打开页面用http协议打开
<script type=module> //2.模块化环境 只有当前环境能用,更安全 打开页面用http协议打开 import student from ./02-es6.js console.log(student); </script> <script> //不能用 console.log(student); </script> 三 nodejs --CMD版本模块化开发
1.导入:require
let student = require(./03 nodejs 模块化开发exp) console.log(student); console.log(student.name); student.sayHello() 2.导出: exports
module.exports = { name: 邓余香, sayHello() { console.log(js简单); } } 3.文件目录下打开cmd
四 nodejs自带模块
1 .js 分为三大部分:es dom bom
2.完全不支持
// console.log(document); 完全不支持dom // document.write 不支持 // console.log(location);不支持 // console.log(object); 3.支持
setInterval setTimeout 支持 console.log(); var a=100 console.log(global); console.log(global.a);//不挂载全局变量 console.log( __dirname); 五 fs
1 nodejs 模块功能--异步开发
2 读文件 异步读取
fs.readFile(./05-nodejs.txt, function (err, data) { if (!err) { console.log(111); console.log(data.toString()) } }) 3 读文件 同步读取
let data = fs.readFileSync(./05-nodejs.txt) console.log(data.toString()); console.log(222); 4 写文件 覆盖原有内容
fs.writeFile(./05-nodejs.txt, yanaaaaaaaaaa, function (err) { err ? console.log(写失败) : console.log(写成功); }) 5 写文件 追加内容
fs.appendFile(./05-nodejs.txt, \我叫邓余香, function (err) { err ? console.log(写失败) : console.log(写成功); }) 6 理解异步 先执行同步,在执行异步
程序不会等他写完在运行完,而是执行了但是没有打印这种
比如淘宝下单,买了abc,但是abc到的时间不确定.就是谁先打印不确定
7创建文件夹
fs.mkdir('./tmp/a/apple', { recursive: true }, (err) => { if (err) throw err; }); 六 http
1 解决中文乱码
2 连接服务器
3 谷歌浏览器的测试会默认补充发起一个请求网页logo 图标的请求
4 response.end 结束http 的返回值
let http = require(http) let fs = require(fs) let app = http.createServer(function (request, response) { response.setHeader(content-type, text/html;charset=utf8)//解决中文乱码 //返回简单数据 // response.end(欢迎你访问我的第一个服务器程序) //返回页面 let data = fs.readFileSync(./01-node简介.html) response.end(data) }) app.listen(8080)// 192.168.12.37: 七 百度网盘案例
url:网址
let http=require(http); let fs=require(fs); http.createServer(function(req,res){ res.setHeader(Content-Type,text/html;charset=utf8);//解决中文乱码 if(req.url==/favicon.ico){ return }else if(req.url==/){ res.end(`<a href=./src>src</a>`) }else{ console.log( __dirname+decodeURI(req.url) );//浏览器发送过来的url 地址 fs.stat(__dirname+decodeURI(req.url), function(err,stats){ if(stats.isFile()){ let imgArr=[png,jpeg,gif]; let fileType=req.url.split(.)[1]; // console.log(1111111); // console.log( imgArr.indexOf(fileType) ); let data=fs.readFileSync(__dirname+req.url); if(imgArr.indexOf(fileType)!=-1){ res.setHeader(Content-Type,image/jpeg;charset=utf8) // res.end(`<img src=${data} />`); } res.end(data); }else{ fs.readdir(__dirname+req.url,function(err,data){ err || data.forEach(ele=>{ res.write(`<a href=${req.url}/${ele}>${ele}</a><br/>`) }) res.end(请求成功!) }) } }) } }).listen(8000,function(){ console.log(服务器创建成功,在8000 端口~) }) 八 复习 定义 三种基本状态 案例
1promise
是一个构造函数,用来解决异步操作,返回一个promise对象
有两个参数 resolve,reject
三种状态
padding:准备阶段
fullfield:异步操作成功
rejected:异步操作失败
let res = new Promise((resolve, reject) => { reject(6666) }) 2 async await
async :返回promise对象
async function getData() { console.log(111); } console.log(getData()); await :必须写在async的内部,返回是执行的结果
async function get() { let res = await getdata() console.log(res); //num console.log(1111); } get() day02
一.服务器返回数据
const http = require(http); const arr = require(./dataModule.js).arr; let app = http.createServer(function (req, res) { console.log(req.method); console.log(req.url); res.setHeader(content-type, text/html;charset=utf-8); if (req.url != /favicon.ico) { //如果客户端请求的数据==arr[]-ele的name===》res.end console.log(decodeURI(req.url.split(=)[1])) arr.forEach(ele => { if (decodeURI(req.url.split(=)[1]) == ele.name) { res.end(JSON.stringify(ele)); } }) } else if (req.url == /favicon.ico) { return; } res.end(没有该用户信息); }) app.listen(8000, function () { console.log(服务器已启动,在8000端口~) });// http://192.168.12.57:8000 二.服务器处理页面和数据
const http=require(http); const arr=require(./dataModule.js).arr; const fs=require(fs); const url=require(url); const querystring=require(querystring); let app=http.createServer(function(req,res){ res.setHeader(content-type,text/html;charset=utf-8); req.url=url.parse( req.url );//将发送过来的地址字符串处理为对象 if(req.url.pathname==/){// http://localhost:8000 //静态资源代理 a href link script src img src let data=fs.readFileSync(./src/login.html); res.end(data.toString()) }else if(req.url.pathname==/favicon.ico){ return; }else if( req.url.pathname== /login_success){//路由 接口 req.url.query=querystring.parse( req.url.query);//处理参数为对象 arr.forEach(ele=>{ if( ele.name== req.url.query.username && ele.passWord==req.url.query.pass){ res.write(登陆成功!); res.end( JSON.stringify(ele) ); } }) } res.end(登陆失败!) }) app.listen(8000,function(){ console.log(服务器已启动,在8000端口~) }); 四 客户端发起ajax
网络通信技术 ajax 页面局部刷新技术 异步
1创建对象 xhr
2 xhr.open(method,path)
3 xhr.send()
4xhr.onreadyStateChange()
监听readyState+网络状态码200
const http=require(http); const arr=require(./dataModule.js).arr; const fs=require(fs); const url=require(url); const querystring=require(querystring); let app=http.createServer(function(req,res){ res.setHeader(content-type,text/html;charset=utf-8); req.url=url.parse( req.url );//将发送过来的地址字符串处理为对象 if(req.url.pathname==/){// http://localhost:8000 let data=fs.readFileSync(./src/login.html); res.end(data.toString()) }else if(req.url.pathname==/favicon.ico){ return; }else if( req.url.pathname== /login_success && req.method==GET){ req.url.query=querystring.parse( req.url.query);//处理参数为对象 arr.forEach(ele=>{ if( ele.name== req.url.query.username && ele.passWord==req.url.query.pass){ let obj={} obj.msg=登陆成功! obj.data=JSON.stringify(ele); res.end( JSON.stringify(obj) ); } }) }else if( req.url.pathname== /login_success && req.method==POST ){ let postData=; req.on(data,function(str){ postData+=str.toString() }) req.on(end,function(){ console.log(postData); postData=querystring.parse(postData) arr.forEach(ele=>{ if( ele.name== postData.username && ele.passWord==postData.pass){ res.write(登陆成功!); res.end( JSON.stringify(ele) ); } }) }) } else{ res.end(登陆失败!) } }) app.listen(8000,function(){ console.log(服务器已启动,在8000端口~) }); 三 post和get区别
1安全性:post比get高
2传输方式:get发送到地址栏
3传输数据:get发送的数据大小限制在4kb左右,post不限制
4速度:get要快一点
5缓存 get可以存在缓存中,post不行
6书签 get可以被书签收藏 post不行
7 浏览器历史:get会将数据存在浏览器历史中,而post不行
8 历览器刷新或者回退时:get请求无害,post数据会重新提交
9 编码格式 get只能用ascii编码 post没有限制
10 数据请求时 get是将数据中的header和data一起发给服务器 返回200code
post先将数据中的header发给服务器,返回100code 在将data发给服务器,返回200xode
11get发送一次tcp数据包给服务器,而post发送两次
五 原生xhr的使用步骤
1创建对象 xhr
2 xhr.open(method,path)
3 xhr.send()
4xhr.onreadyStateChange()
六 网络状态码 200 400 404 403 500 503……
1xx:请求已被接受,但是需要进一步处理
2XX:请求已被接受,理解
3xx:客户端需要进一步操作,用来重定向,
4xx请求错误
5xx:服务器在处理请求的过程中有错误或者异常
200 OK 请求处理成功,返回相关信息
400 Bad Request 请求报文存在语法错误。需要修正请求报文后再次发送请求
404 Not Found 服务器上无法找到被请求的资源、
403 Forbidden 请求资源的访问被服务器拒绝。服务器没必要给出拒绝的理由。
500 Internet Server Error 服务器在执行请求时发生了错误。可能是Web应用存在的bug 或者临时的障碍
503 Service Unavailable 服务器处于超载或者故障状态。如果事先得知何时可以解决故障,可以将时间写入Retry-after首部字段再返回给客户端。
204 No Content 请求处理成功,但响应报文没有主题返回
206 Partial Content 客户端进行了范围请求,服务器成功执行请求并返回指定范围的实体内容
301 Moved Permanently 永久性重定向。请求的资源已经被分配到新的url
302 Found 临时性重定向
304 Not Modified 客户端发送附带条件的请求后,服务器允许请求,但内容并没修改,返回304。即客户端可以使用缓存的内容
xhr.readyState
0 请求没有初始化
1 请求已经建立,还没发送
2请求已经发送 还在处理
3请求正在处理
4响应完成
七 ajax xhr
async js and xml
xml http request
八 前后端概念
客户端:
硬件:手机、平板、笔记本、台式机、电视机、智能手表、电器、售货机;
软件:浏览器、QQ、微信、各种APP等;
服务器端:
硬件:服务器,就是电脑,配置非常好,设备;
软件:Apache、Nginx、IIS、Tomcat等,nodejs可以创建服务器。
Web服务器:提供网页访问的;
前端:界面端 app web=> html css js
后端: PHP java node等等
九客户端常用请求方式
1 在浏览器中输入网址发出get请求
2 css js img自动发出get请求
3 超链接发出get请求
4 js发出get请求
location.href=
5表单提交发出请求(get或post)
6ajax请求
十 网络通信OSI模型
客户端 http--服务器
网络通信OSI模型 ----
物理层
data:发送的是0101 二进制数据,连接网线
链路层
mac 地址(本机+服务器)+data,局域网下
网络层
ip 地址(本机+服务器)+mac 地址(本机+服务器)+data,公网
传输层
ip 地址(本机+服务器)+port端口号+mac 地址(本机+服务器)+data,具体应用
应用层
http协议+ip 地址(本机+服务器)+port端口号+mac 地址(本机+服务器)+data,具体的规则
十一 http协议:(数据包/报文)
request
请求行----数据方法 (今天学……)
请求头----url\content-type\accept\Cache-Control……
请求体----文件上传、用户名、密码……
response
请求头----url\content-type\accept\Cache-Control……
请求体----成功或是失败、图片、网页
状态码----404 200 500 501 503
day03
一 ajax请求服务器 get
let http = require(http); let fs = require(fs); let url = require(url); const querystring = require(querystring); let userData = require(./userModule.js).arr; http.createServer(function (req, res) { fs.readFile(__dirname + /src + req.url, function (err, data) { if (!err) { res.end(data); } else if (url.parse(req.url).pathname == /login_success) { let queryStr = url.parse(req.url).query let queryData = querystring.parse(queryStr); for (var i = 0; i < userData.length; i++) { if (userData[i].name == queryData.username && userData[i].passWord == queryData.pass) { res.end(登陆成功!); break; } } if (i == userData.length) { res.end(登陆失败!) } } else { res.setHeader(content-type, text/html;charset=utf8) res.end(404请求!<a href='http://localhost:8000/login.html'>请跳转登录页面</a>) } }) }).listen(8000, function () { console.log(服务器已启动,在8000端口~) }) document.querySelector(button).onclick = function () { let xhr = new XMLHttpRequest(); xhr.open(get, `http://localhost:8000/login_success?username=${username.value}&pass=${pass.value}`); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { if (xhr.responseText == 登陆成功!) { location.href = https://www.baidu.com; } else { alert(xhr.responseText) } } } } 二 ajax请求服务器 post
if (i == userData.length) { res.end(登陆失败!) } } else if (url.parse(req.url).pathname == /login_success && req.method == POST) { console.log(1111) let clientData = ; req.on(data, function (str) { clientData += str; }) req.on(end, function () { console.log(clientData) clientData = querystring.parse(clientData) res.setHeader(content-type, text/html;charset=utf8) // res.end(预备开始判断) for (var i = 0; i < userData.length; i++) { if (userData[i].name == clientData.username && userData[i].passWord == clientData.pass) { res.end(登陆成功!); break; } } if (i == userData.length) { res.end(登陆失败!) } //判断登录成功/登陆失败---for循环 }) } 三 ajax请求服务器 封装ajax 回调函数 promise
回调函数
<script src=./tool.js></script> <script src=>//回调函数--封装ajax document.querySelector(button.ajax1).onclick=function(){ ajax(http://localhost:8000/ajax1,function(data){ document.querySelector(div.ajax1).innerHTML=data }) } function ajax(url,fn){ let xhr=new XMLHttpRequest; xhr.open(get,url); xhr.send(); xhr.onreadystatechange=function(){ if(xhr.readyState==4&& xhr.status==200){ fn(xhr.responseText) } } } peomise
<script>//Promise--封装ajax document.querySelector(button.ajax1).onclick=function(){ myAxios(http://localhost:8000/ajax1).then(res=>{ document.querySelector(div.ajax1).innerHTML=res }) } function myAxios(url){ return new Promise((res,rej)=>{ let xhr=new XMLHttpRequest; xhr.open(get,url); xhr.send(); xhr.onreadystatechange=function(){ if(xhr.readyState==4&& xhr.status==200){ res(xhr.responseText) } } }) } 四 ajax请求服务器 jquery和axios
jquery
<script src=https://cdn.bootcss.com/jquery/3.6.0/jquery.min.js></script> document.querySelector(button.ajax1).onclick=function(){ $.ajax( { url:http://localhost:8000/ajax1, success:function(result){ document.querySelector(div.ajax1).innerHTML=result } } ); } axios
<script src=https://unpkg.com/axios/dist/axios.min.js></script> document.querySelector(button.ajax2).onclick=function(){ axios(http://localhost:8000/ajax2).then(res=>{ console.log(res) alert(res.data); document.querySelector(div.ajax2).innerHTML=res.data }) } 五 ajax请求服务器 fetch
<!-- 浏览器自带的 工具---fetch-发起网络请求案例 --> <script> document.querySelector(button.ajax2).onclick=function(){ fetch(http://localhost:8000/ajax2) .then(res=>res.text())//发起请求之后需要做数据格式处理 .then(res=>{ alert(res); document.querySelector(div.ajax2).innerHTML=res; }) } // 浏览器自带的 工具--fetch--语法 --> console.log( fetch ) fetch(http://localhost:8000/ajax1).then(res=>{ console.log(111); console.log(res); return res.text() }).then(res=>{ console.log(222); console.log(res) }) </script> 七 url地址
res.setHeader(Access-Control-Allow-Origin,*); 服务器ip:192.168.12.57 localhost
服务器port:8000
服务器req.url ----/user/login_success?useranme=司水花&password=123456&kw=teacher
路由地址:/user/login_success
请求参数:useranme=司水花&password=123456&kw=teacher
八
静态资源代理:服务器可以返回.html .css .js .png…… 给客户端
路由(接口):服务器可以接收客户端发送的数据,再返回给客户端对应数据的功能
day04
一 什么情况下会引起跨域?以及解决方法
跨域是由于浏览器的同源策略问题导致的,就是指浏览器不执行其他网站脚本
同源指的是协议,域名,端口都要保持一致,三者有一个不同就会导跨域
当一个页面中发起ajax请求访问另一个地址时,这个页面的地址与ajax地址的三者必须一致
从一个页面使用 ajax 访问另一个页面,浏览器有同源策略(协议、域名、端口号)
处理跨域的方式:
cors----res.setHeader(……,from一个页面 )
优点:简单、方便;缺点:安全,修改服务器代码
1 cors
设置让服务器的请求头允许资源共享
简单方便 不安全
在creatserevr中加
res.setHeader(Access-Control-Allow-Origin,*); 2 jsonp
jsonp----JSON with Padding----script标签
script标签scr属性 借助于script获取到数据之后将数据作为js代码在执行
3代理
代理----自己的页面访问自己的服务器,服务器去向另外一台服务器发起请求
ajax向页面当前所在的地址(服务器1)发起请求,服务器1向服务器2发起请求
二 npm
1 安装好node环境之后,环境中的一个命令
2本地安装
npm install 模块1 模块2 --save 模块下载 安装的模块包名字保存在package.json中
npm install 模块@12.6.8 规定版本号
npm i 简写
npm uninstall 卸载
3 package.json
npm init -y 文件中不能包含中文
4 全局安装 -g
npm install nodemon -g
此操作之后不用每次改完都重启服务器
三 egg-exam
1 快速入门
1安装
npm i egg-init -g 2 启动项目
npm run dev 3服务器基本信息配置
在 config里面
配置端口号
config.cluster = { listen: { path: '', port: 8000, hostname: 'admin.jianmian.com',//默认localhost和ip地址,上线时用0.0.0.0 } }; 4 静态资源托管
在public下创建html文件
用这个访问
http://192.168.12.37:8000/public/index.html 2 跨域
先配置
npm i --save egg cors
开启插件
开启插件:// config/plugin.js
cors:{ enable: true, package: 'egg-cors', } 配置cors:// config/config.default.js
// 跨域的配置 config.cors = { origin: '*', allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH' }; 3 基础功能
1框架约定目录规则
1app/router.js 配置URL路由规则
2app/controller 解析用户的输入,处理后返回相应的结果
3app/service 编写业务逻辑
4app/public 放置静态资源
5config/config.{env}.js 编写配置文件
6config/plugin.js 配置需要加载的文件
2 内置对象
1 application
全局应用对象,在一个应用中,只会实例化一个对象
在继承于cotroll,service基类的实例中,可以通过this.app来访问到application对象
2 request&response
可以在context的实例上获取到当前请求的request(ctx.request)和response(ctx.response)
3controller
属性:
ctx:当前请求的context实例
app:应用的application实例
service:应用所有的service
4 service
推荐所有的service都继承该基类
service和controll基类属性一致
3路由router
路由是描述url和具体承担执行动作的controll的对应。
说的直白点就是用户访问不同的路径时对应的应该有不同的controll去响应
router.get('/getdata', controller.form.get); router.post('/pdata', controller.form.post); router.get('/user/:userid', controller.user.info); 4. 控制器Controller
5. 获取提交的数据
day05
一 浏览器获取一个url 地址之后渲染出页面的流程是怎样的?
1在浏览器地址栏输入url
2浏览器先查看浏览器缓存--系统缓存--路由缓存,如果缓存有,直接显示,如果没有,跳转第三步
2.1 浏览器缓存:浏览器会记录dns一段时间,只是第一个地方解析dns请求
2.2操作系统缓存:如果浏览器缓存中没有记录,系统就会调用操作系统,获取笑傲做系统的记录
2.3路由缓存:上述两个都没有dns记录,搜索路由缓存
2.4isp缓存:上述均失败,继续向isp搜索
3发送http请求前,域名解析(dns解析)
通过域名查到具体的ip,
4 浏览器向服务器发送tcp连接,与浏览器三次握手
4.1 客户机向服务器打电话
4.2 服务器接听电话
4.3 客户机:”听得到吗?“-----确保数据没有被篡改
5 TLS握手
如果文件加密的话,才会有这一步
6 解析文件
6.1生成dom树,解析css样式,js交互
6.2生成render树
7 调用gpu绘制,合成图层,将内容显示屏幕上
8 客户端与服务器交互
9 ajax查询
二 数据库
一 数据库认识
DBMS:database manager system 数据库管理系统
数据库:
表格
表头:(姓名,性别)
数据:记录tr
二 安装软件,一定要避免重复 安装
三 sql语句
增
insert into student(name,age) values('邓余香',18) 删
delete from student where name==邓余香 改
update student set name='amy' 查
1 普通查询
selectt name from student selectt * from student 2 条件查询
select *from student where id=2 查询salary 工资大于6251 的那些记录里的姓名name 和工资salary
select name,salary from employee where salary>6251 3 条件模糊查询 like or and
查询名字姓李 的那些记录里的姓名name 和工资salary
select name,salary from employee where name like'李%' //'&李' '%李%' 4 条件范围查询 in
between and
not in
查询id 为1、或10、或20 的那些记录里的所有信息
select * from student where id in(1,10,20) 查询id 在13~23 之间的那些记录里的所有信息
select * from student where id between 12 and 23 5 分页查询
SELECT 字段1,字段2 FROM 表名 limit 总量*(页码-1),总量
查询第1 页8 条记录的id,姓名NAME,工资salary
select name,salary from employee limit 0,8 6 关联 两张表一定要建立联系
查询工资大于8000 的员工的id,姓名NAME,工资salary,及其所属部门名dname
select id,name,salary,dname from employee,dept where salary>8000 and employee.deptid=dept.dptid 7.函数
Max Min count Avg sum!!!不能直接将函数用在where条件语句中!!!
查询employee 表格里的总人数
select count(id) from employeee 查询employee 表格里工资为最高工资的人的所有信息
select * from employee,dept where salary= (select max(salary)from employee)and employee.deptid=dept.dptid 8 分组查询 group by
注意一般分组之后用函数查结果
查询每个部门的总人数
select count(*),employee.deptid,dept.dname from employee,deptid where employee.deptid=dept.dptid group by employee.deptid 查询每个部门的最高工资!!!注意一般分组之后用函数查结果!!
select max(salary),employee.deptid,dept.dname from employee,deptid where employee.deptid=dept.dptid gruop by employee.deptid 查询每个部门的最高工资,以及该部门的名称、deptid
select max(salary)as maxsalary,dept.dname, dept.depid from employee,deptid where employee.deptid=dept.dptid gruop by employee.deptid 9 having
对分组之后的结果进行条件过滤!!!在having 条件后边可以用函数!!!
查询月工资总数在65000 以上的部门信息
sdelect *from employee,dept group by deptid having sun(salary)>65000 10 嵌套查询
查询人员姓名-->该人工资需要是该部门的最高工资
select a.name,b.maxsalary,b.deptid,b.dname from employee as a,(select max(salary)from employee)as b where a.salary=b.maxsalary 11排序--order by 字段 ASC/DESC
查询工资大于8000 的员工信息,并且结果按照名称name 中文拼音升序排列
select * from employee where salary>8000 order by convert(name using gbk) aesc 练习
1从shop goods里查出第10页的数据,每页显示20条
select *from shop goods limit 180,20 2从shop_ goods里查出关键词包含连衣裙的第3页的数据,每页显示20条
select *from shop goods where kw like%连衣裙%limit 40,20 3从employee表中查出工资高于平均工资的姓王的员工
select * from employee where salary>(seclect avg(salary)from salary) and name like '王%' 4查询平均工资在8000以上的部门,以及该部门门的名称、该部门的id
SELECT AVG(salary),dept.dptid,dept.dname FROM employee,dept WHERE employee.deptid=dept.dptid GROUP BY employee.deptid HAVING AVG(salary)>8000 5查询每个部门员工的工资大于平均工资的总人数,以及该部门的名称、该部门的id
SELECT COUNT(*),c.dname,c.deptid (select * from employee,a,(select avg(salary) as avgs ,dept.dptid,dept.dname from employee ,dept WHERE employee.deptid=dept.dptid GROUP BY employee.deptid)b where a.salary>b.avgs and a.deptid=b.dptid)as c group by c.deptid 四 数据设计规范 三范式
第一范式: 字段信息不可分割
第二范式:数据表格关联关系---建新表
第三范式:数据表格关联关系---用外键
如
菜谱表
id name 步骤
配料表
id name 单位
关联表
id 菜谱的id 配料的id 用量
三 作业
1、http 与https 的区别有哪些?
https:hypertext transfer protocol secure 超文本传输安全协议,一种网络安全协议,在http的基础上加了SSL/TLS协议来进行数据加密,保护数据不被泄露和窃取
通俗的来说,我们登录一个网站时,在填写表单提交后,我们提交的信息可能会被黑客截获
但是,若是访问ssl加密的网站也就是https协议的网站,浏览器将与该网站建立有友好加密的通道,保护我们的数据不被泄露,没有人可以查看或访问在浏览器中输入的内容,保证数据传输的安全
区别:

1 https要申证书 https不需要
2 http属于应用层信息传输,https是由SSL+http构建的可进行加密传输,身份认证的网络协议,比http更安全
3 两者使用的是完全不同的链接方式,用的端口也不一样,前者是80,后者是443
4http连接简单,无状态,https是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,比http安全
2、http1.0 http2.0 http3.0 各有什么不同?
http:hypertext transfer protocol 朝我文本传输协议 ,所有www文件都要遵守这个标准,
http1.0:
连接问题:连接无法复用,没发送一个请求都要三次握手,重新建立连接,效率低
阻塞问题:下一个请求的发送必须要等到上一个请求返回后才会进行,如果上一个请求没有没有返回,那么后面的数据就会全部阻塞
安全问题;传输的内容店铺是明文,无法保证数据的安全性
http2.0
专注于性能,采用二进制格式传输数据,
采用了多路复用的技术,可以只通过一个tcp连接来传输所有的请求数据
采用了头部压缩技术,成功解决了http1.0的header里携带的内容过大的问题,在一定程度上减轻了传输的成本,但是也存在问题,要是传输过程中出现丢包的情况,就要整个tcp重传,后面的资源就会被堵塞
http3.0
放弃了tcp改用QUIC协议,quic基于UDP协议,UDP无需三次握手四次挥手,传输速率高
改善了多路复用产生的问题,要是出现丢包,就只需要重传丢掉的包