苏州网站建设推广咨询平台,做网站的公司图,企业网站的建设目的有哪些,蕲春网站建设回顾1. DQL单表高级查询条件 where比较运算逻辑运算符in关键字between关键字if null关键字like关键字% 多个任意字符_ 单个任意字符排序 order byascdesc聚合函数count(*) 统计行#xff0c;包括null值maxminavgsum分组 group by 分组字段 having 分组后条件过滤分页 limit 开…回顾1. DQL单表高级查询条件 where比较运算逻辑运算符in关键字between关键字if null关键字like关键字% 多个任意字符_ 单个任意字符排序 order byascdesc聚合函数count(*) 统计行包括null值maxminavgsum分组 group by 分组字段 having 分组后条件过滤分页 limit 开始索引每页显示个数公式索引当前页-1× 每页的个数
2. 数据库约束主键约束create table 表名(id int primary key auto_increment,....);唯一 unique非空 not null默认值 default3. 表关系一对多主表从表外键字段 指向 主表主键多对多二个主表创建第三张作为从表二个外键字段 分别指向 各自主表的主键由多个一对多组成一对一外键是唯一主键是外键外键约束保证多表有关的数据进行限定保证他的正确性有效性和完整性[constraint] [约束性] foreign key(外键字段) references 主表主键4. 数据库备份与还原MySQL多表查询与事务今日目标1. DQL多表高级查询语法笛卡尔积内连接外连接子查询2. 多表综合案例四张表学习多表查询的规律3. 事务安全TCL转账案例引入它解决场景4. 表的范式数据库的设计规则一 多表查询【重点】同时查询多张表获取到需要的数据组成完整的信息返回给用户。准备数据-- 多表查询
create database web03_1;
use web03_1;
-- 创建部门表主表
CREATE TABLE dept (id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20)
);INSERT INTO dept (NAME) VALUES (开发部),(市场部),(财务部),(销售部);-- 创建员工表从表
CREATE TABLE emp (id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10),gender CHAR(1), -- 性别sexsalary DOUBLE, -- 工资join_date DATE, -- 入职日期dept_id INT -- 外键字段
);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(孙悟空,男,7200,2013-02-24,1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(猪八戒,男,3600,2010-12-02,2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(唐僧,男,9000,2008-08-08,2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(白骨精,女,5000,2015-10-07,3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(蜘蛛精,女,4500,2011-03-14,1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(沙僧,男,6666,2017-03-04,null);1.1 笛卡尔积* 功能二张表的记录所有字段进行了组合这种现象称为笛卡尔积又称为交叉连接
* 语法SELECT ... FROM 左表,右表;1.2 内连接* 功能拿左表的记录去匹配右表的记录若匹配上就显示匹配不上就不显示二张表的交集
* 语法1.隐式内连接【了解】SELECT ... FROM 左表,右表 where 条件过滤;2.显示内连接【推荐】 select ... from 左表 [inner] join 右表 on 条件过滤;
-- 隐式内连接
SELECT * FROM emp e,dept d WHERE e.dept_id d.id;
-- 显示内连接
SELECT * FROM emp e INNER JOIN dept d ON e.dept_id d.id;# 内连接
-- 查询唐僧的 id姓名性别工资和所在部门名称
SELECT e.id,e.name,e.gender,e.salary,d.name FROM emp e INNER JOIN dept d ON e.dept_id d.id WHERE e.name 唐僧;1.3 外连接1. 左外连接【掌握】功能展示左表的全部记录去匹配右表的记录若匹配上显示数据若没匹配上显示NULL语法select ... from 左表 left [outer] join 右表 on 条件过滤;2. 右外连接【了解】功能展示右表的全部记录去匹配左表的记录若匹配上显示数据若没匹配上显示NULL语法select ... from 左表 right [outer] join 右表 on 条件过滤;
# 左外连接
-- 查询所有员工信息左边及对应的部门名称右边
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id d.id;
-- 查询所有部门左边及对应的员工信息右边
SELECT * FROM dept d LEFT OUTER JOIN emp e ON e.dept_id d.id;# 右外连接
-- 查询所有部门右边及对应的员工信息左边
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON d.id e.dept_id;1.4 子查询* 功能一条select语句执行结果作为另一条select 语法 的一部分使用需要添加括号
* 语法1. 单值SELECT MAX(salary) FROM emp;2. 单列多行SELECT NAME FROM emp;3. 多列多行SELECT * FROM emp;* 小结子查询结果为单列作为条件在where后使用select ... from 表名 where 字段 or in(子查询)子查询结果为多列作为虚拟表在form后使用select ... from (子查询) as 表别名....
# 子查询# 子查询结果为单值
-- 1 查询工资最高的员工是谁
SELECT * FROM emp WHERE salary (SELECT MAX(salary) FROM emp);
-- 2 查询工资小于平均工资的员工有哪些
-- 2.1 先求出平均工资
SELECT AVG(salary) FROM emp;
-- 2.2 再查询小于平均工资的员工
SELECT * FROM emp WHERE salary (SELECT AVG(salary) FROM emp);# 子查询结果为单列多行
-- 1 查询工资大于5000的员工来自于哪些部门的名字
-- 1.1 查询工资大于5000的员工
SELECT dept_id FROM emp WHERE salary 5000;
-- 1.2 来自于哪些部门的名字
SELECT * FROM dept WHERE id IN(SELECT dept_id FROM emp WHERE salary 5000);-- 2 查询开发部与财务部所有的员工信息
-- 2.1 查询开发部与财务部
SELECT id FROM dept WHERE NAME IN(开发部,财务部);
-- 2.2 对应的的员工信息
SELECT * FROM emp WHERE dept_id IN(SELECT id FROM dept WHERE NAME IN(开发部,财务部));# 子查询结果为多列多行
-- 1 查询出2011年以后入职的员工信息包括部门名称
-- 1.1 查询出2011年以后入职的员工信息
SELECT * FROM emp WHERE join_date 2011-1-1;
-- 1.2 作为虚拟表连接部门表
SELECT * FROM (SELECT * FROM emp WHERE join_date 2011-1-1) AS e LEFT JOIN dept d ON e.dept_id d.id;-- 扩展
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.dept_id d.id WHERE e.join_date 2011-1-1;二 多表案例【四张表】我们在企业开发时根据不同的业务需求往往需要通过2张及以上的表中去查询需要的数据。其实不管是几张表的查询都是有规律可循的。 准备数据-- 多表案例
create database web03_2;
use web03_2;
-- 部门表
CREATE TABLE dept (id INT PRIMARY KEY auto_increment, -- 部门iddname VARCHAR(50), -- 部门名称loc VARCHAR(50) -- 部门位置
);-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES
(10,教研部,北京),
(20,学工部,上海),
(30,销售部,广州),
(40,财务部,深圳);-- 职务表
CREATE TABLE job (id INT PRIMARY KEY,jname VARCHAR(20), -- 职务名称description VARCHAR(50) -- 职务描述
);-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, 董事长, 管理整个公司接单),
(2, 经理, 管理部门员工),
(3, 销售员, 向客人推销产品),
(4, 文员, 使用办公软件);-- 员工表
CREATE TABLE emp (id INT PRIMARY KEY, -- 员工idename VARCHAR(50), -- 员工姓名job_id INT, -- 职务id 外键mgr INT , -- 上级领导joindate DATE, -- 入职日期salary DECIMAL(7,2), -- 工资 99999.99bonus DECIMAL(7,2), -- 奖金 99999.99dept_id INT, -- 所在部门编号 外键CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
(1001,孙悟空,4,1004,2000-12-17,8000.00,NULL,20),
(1002,卢俊义,3,1006,2001-02-20,16000.00,3000.00,30),
(1003,林冲,3,1006,2001-02-22,12500.00,5000.00,30),
(1004,唐僧,2,1009,2001-04-02,29750.00,NULL,20),
(1005,李逵,4,1006,2001-09-28,12500.00,14000.00,30),
(1006,宋江,2,1009,2001-05-01,28500.00,NULL,30),
(1007,刘备,2,1009,2001-09-01,24500.00,NULL,10),
(1008,猪八戒,4,1004,2007-04-19,30000.00,NULL,20),
(1009,罗贯中,1,NULL,2001-11-17,50000.00,NULL,10),
(1010,吴用,3,1006,2001-09-08,15000.00,0.00,30),
(1011,沙僧,4,1004,2007-05-23,11000.00,NULL,20),
(1012,李逵,4,1006,2001-12-03,9500.00,NULL,30),
(1013,小白龙,4,1004,2001-12-03,30000.00,NULL,20),
(1014,关羽,4,1007,2002-01-23,13000.00,NULL,10);-- 工资等级表
CREATE TABLE salarygrade (grade INT PRIMARY KEY, -- 等级losalary INT, -- 最低工资hisalary INT -- 最高工资
);-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);练习-- 1 查询所有员工信息。显示员工编号员工姓名工资职务名称职务描述
-- 1.1 确定查询哪些表【员工 职务】
SELECT * FROM emp e INNER JOIN job j ;
-- 1.2 确定连接条件【员工(job_id) 指向 职务(id)】
SELECT * FROM emp e INNER JOIN job j ON e.job_id j.id;
-- 1.3 确定显示字段【员工编号员工姓名工资职务名称职务描述】
SELECT e.id,e.ename, e.salary,j.jname,j.descriptionFROM emp e INNER JOIN job j ON e.job_id j.id;
-- 2 查询所有员工信息。显示员工编号员工姓名工资职务名称职务描述部门名称部门位置
-- 2.1 确定查询的表【员工、职务、部门】
SELECT * FROM emp e INNER JOIN job j INNER JOIN dept d;
-- 2.2 确定连接条件【员工(job_id) 指向 职务(id)、员工(dept_id) 指向 部门(id)】
SELECT * FROM emp e INNER JOIN job j INNER JOIN dept dON e.job_id j.id AND e.dept_id d.id; -- 了解SELECT * FROM emp e INNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.id; -- 推荐
-- 2.3 确定显示字段【显示员工编号员工姓名工资职务名称职务描述部门名称部门位置】
SELECT e.id,e.ename, e.salary,j.jname,j.description,d.dname,d.locFROM emp e INNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.id; -- 推荐
-- 3 查询所有员工信息。显示员工姓名工资职务名称职务描述部门名称部门位置工资等级
-- 3.1 确定查询表【员工、职务、部门、工资等级】
SELECT * FROM emp eINNER JOIN job jINNER JOIN dept dINNER JOIN salarygrade sg;
-- 3.2 确定连接条件【员工(job_id) 指向 职务(id)、员工(dept_id) 指向 部门(id)、员工(salary) 范围查找 对应工资等级】
SELECT * FROM emp eINNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.idINNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;
-- 3.3 确定显示字段【显示员工姓名工资职务名称职务描述部门名称部门位置工资等级】
SELECT e.id,e.ename, e.salary,j.jname,j.description,d.dname,d.loc,sg.gradeFROM emp eINNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.idINNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;小结1. 多表查询会出现笛卡尔积2. 消除笛卡尔积2张表1个条件、3张表2个条件【条件n-1】3. 步骤3.1 确定查询几张表3.2 确定连接条件3.3 确定显示字段3.4 确定业务条件
-- 4 查询经理的信息。显示员工姓名工资职务名称职务描述部门名称部门位置工资等级
-- 4.1 确定查询几张表
SELECT * FROM emp eINNER JOIN job jINNER JOIN dept dINNER JOIN salarygrade sg;
-- 4.2 确定连接条件
SELECT * FROM emp eINNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.idINNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;
-- 4.3 确定显示字段
SELECT e.id,e.ename, e.salary,j.jname,j.description,d.dname,d.loc,sg.gradeFROM emp eINNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.idINNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;
-- 4.4 确定业务条件【经理】
SELECT e.id,e.ename, e.salary,j.jname,j.description,d.dname,d.loc,sg.gradeFROM emp eINNER JOIN job j ON e.job_id j.idINNER JOIN dept d ON e.dept_id d.idINNER JOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalaryWHERE j.jname 经理;
-- 5 查询出部门编号、部门名称、部门位置、部门人数
-- 5.1 先查询部门人数
SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id;-- 5.2 查询结果作为虚拟表 连接 部门表
SELECT * FROM (SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id) AS e INNER JOIN dept d ON e.dept_id d.id;-- 内连接不关注书写的顺序谁先谁后都可以
SELECT d.id,d.dname,d.loc,e.total FROM dept d INNER JOIN (SELECT dept_id,COUNT(*) AS total FROM emp GROUP BY dept_id) AS e ON d.id e.dept_id;三 事务安全 TCL3.1 概述如果一个包含多个步骤的业务操作被事务管理那么这些操作要么同时成功要么同时失败。准备数据-- 创建数据表
CREATE TABLE account ( -- 账户表id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(32),money DOUBLE
);-- 添加数据
INSERT INTO account (NAME, money) VALUES (片王, 1000), (刚刚, 1000);模拟转账-- 转账
-- 片王扣钱 -100
UPDATE account SET moneymoney-100 WHERE id 1;
-- 机器故障
-- 刚刚收钱 100
UPDATE account SET moneymoney100 WHERE id 2;3.2 操作3.2.1 手动提交事务1. 开启事务start transaction;2. 提交事务commit;3. 回滚事务rollback;转账成功-- 1.开启事务
start transaction;
-- 2.片王扣钱
UPDATE account SET moneymoney-100 WHERE id 1;
-- 3.刚刚加钱
UPDATE account SET moneymoney100 WHERE id 2;
-- 4.提交事务
commit;转账失败-- 1.开启事务
start transaction;
-- 2.片王扣钱
UPDATE account SET moneymoney-100 WHERE id 1;
-- 机器故障
-- 3.回滚事务
rollback;3.2.2 自动提交事务* MySQL数据库默认情况一条DML语句就是一个独立的事务。* 查看MySQL是否开启自动提交show variables like autocommit;* 临时关闭自动提交set autocommitOFF;测试还会不会自动提交-- 片王扣钱
UPDATE account SET moneymoney-100 WHERE id 1;
-- 手动提交事务
commit;3.3 事务原理【理解】注意代码报错之后必须进行rollback处理如果没有执行rollback 会影响到同一个事务中下一次提交数据。3.4 回滚点【了解】* 功能当事务开启后一部分sql执行成功添加一个回滚点后续操作报错了直接到回滚点保证之前的操作可以成功提交* 语法1.添加保存点savepoint 保存点名称;2.回滚到保存点rollback to 保存点名称;模拟插入四条记录在前二条插入成功后设置保存点后续操作报错了直接到保存点保证前二条记录可成功提交。-- 1.开启事务
start transaction;
-- 2.插入 小路
insert into account values(null,小路,1000);
-- 3.插入 PGONE
insert into account values(null,pgone,1000);
-- 4.设置保存点
savepoint ok;
-- 5.插入 薛之谦
insert into account values(null,谦谦,1000);
-- 机器故障
-- 6.回滚到保存点
rollback to ok;
-- 7.提交事务
commit;3.5 事务特性【ACID】【面试题】1. 原子性A atomicity如果一个包含多个步骤的业务操作被事务管理那么这些操作要么同时成功要么同时失败。2. 一致性C consistency数据在事务的执行前后保证它的完整一致3. 隔离性I isolation多个事务之间相互独立互不干扰4. 持久性D durability事务一旦成功提交同步到数据库磁盘文件不可逆。3.6 事务隔离性* 功能多个事务之间隔离的相互独立的。但是如果多个事务操作同一批数据则会引发一些问题设置不同的隔离级别就可以解决这些问题。1. 脏读一个事务中读取到另一个事务未提交的数据2. 不可重复读一个事务中二次读取的内容不一致update3. 幻读一个事务中二次读取的数量不一致insert、deleteMySQL数据库隔离级别| 级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 | | ---- | -------- | ---------------- | ---- | ---------- | ---- | ------------------ | | 1 | 读未提交 | read uncommitted | 是 | 是 | 是 | | | 2 | 读已提交 | read committed | 否 | 是 | 是 | Oracle和SQL Server | | 3 | 可重复读 | repeatable read | 否 | 否 | 是 | MySQL | | 4 | 串行化 | serializable | 否 | 否 | 否 | |数据库性能1234数据库安全4321综合考量2、3演示不同隔离级别产生的问题开启二个事务A窗口 B窗口1. 查看当前数据库隔离级别show variables like %isolation%;
2. 临时修改隔离级别set session transaction isolation level 级别字符串;update account set money900 where id 1;
3. 演示3.1 脏读 设置隔离级别为 read uncommitted;set session transaction isolation level read uncommitted;3.2 解决脏读 设置隔离级别为 read committed;set session transaction isolation level read committed;3.3 解决不可重复读 设置隔离级别为 repeatable read;set session transaction isolation level repeatable read;4.3 串行化 设置隔离级别 serializable;set session transaction isolation level serializable;四 三范式【了解】4.1 概述* 范式(Normal Form)设计数据库表的规则好的数据库设计对数据的存储性能和后期的程序开发都会产生重要的影响。建立科学的规范的数据库就需要满足一些规则来优化数据的设计和存储 。* 分类目前关系数据库有六种范式第一范式1NF、第二范式2NF、第三范式3NF、巴斯-科德范式BCNF、第四范式(4NF、第五范式5NF又称完美范式。满足最低要求的范式是第一范式1NF。在第一范式的基础上进一步满足更多规范要求的称为第二范式2NF其余范式以次类推。一般说来数据库只需满足第三范式(3NF就行了。4.2 三范式看图1. 第一范式1NF要求每一列不能再拆分
2. 第二范式2NF要求1.一张表只描述一件事情2.表中的每一个普通列都依赖于主键
3. 第三范式3NF要求从表的外键必须使用主表的主键