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
二 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无需三次握手四次挥手,传输速率高
改善了多路复用产生的问题,要是出现丢包,就只需要重传丢掉的包