diff --git "a/55 \346\235\250\346\227\255\344\270\234/20231019\350\257\273\345\217\226.md" "b/55 \346\235\250\346\227\255\344\270\234/20231019\350\257\273\345\217\226.md" new file mode 100644 index 0000000000000000000000000000000000000000..30143c1d6d9884a1f162f4544e5d3c3b2fa99970 --- /dev/null +++ "b/55 \346\235\250\346\227\255\344\270\234/20231019\350\257\273\345\217\226.md" @@ -0,0 +1,133 @@ +# 笔记 + +```sql +事务 概念 + +> 是指对数据库进行的一批操作 +> +> 在同一个事务中,这些操作要么同时成功,要么全部失败. + + 四个特性(ACID) + 原子性:整个过程如原子操作一样,最终要么全部失败,是一个不可分割的最小执行单位,可以由一条或者多条MySQL语句组成 + 一致性:事务完成是,必须使所有数据保持一致状态,即从实际的业务逻辑上来讲,最终结果是对的,且效果和程序员所想的完全符合 + 隔离性:一个事务的执行不能被其他的事务干扰,保证事务在不受外部并发操作的影响的独立环境下运转 + 持久性:事务一旦提交或回滚对数据库的数据改变是永久的 + + 事务操作 + + 隐性事务 +> +> MySQL默认事务是是隐性事务,执行增删改会自动提交,无法回滚 +> +> 查看是否开启自动提交 +> +> ```mysql +> show variables like 'autocommit'; +> ``` +> auto commit显示on表示为开启了自动提交 +> #### 显式提交 +> 开发者手动使用事务来开启,提交,回滚 +> 第一种 +> 设置提交方式,变成手动提交 +> +> SELECT@@autocommit; 查询当前务参数 +> SET @@autocommit=0; 修改当前事务参数,将自动提交变为手动提交 +> 然后执行增删改的操作时, +> 要加 COMMIT 才能将指令反应到数据库中,执行指令, +> 如果出现异常,也可以使用 ROLLBACK 来回滚数据防止数据库出错 +> 第二种 +> ```MySQL +> 手动开启事务 +> START TRANSACTION 或者 BEGIN 开启事务 +> 然后执行增删改的操作时, +> 要加 COMMIT 才能将指令反应到数据库中,执行指令 +> 如果出现异常,也可以使用 ROLLBACK 来回滚数据防止数据库出错 +> 第二种相比于第一种更方便 +> 只要不提交事务,不回滚事务,事务就会一直存在,数据库就不会发生真正的变化。 +> #### savepoint +> 假设在事务里面执行了一大批操作但是只想回滚部分数据,how do? +> 可以用savepoint,创建一个节点,配合rollback使用 +> ```MySQL +> savepoint 名 -- 创建节点 +> rollback to 节点名 -- 回滚至节点处,且不会确定事务 +> 效果类似于游戏存档读档 +> #### rollback +> 回滚,会直接提交事务且将数据还原到初始状态 +> #### 只读事务 +> 效果字如其名,在此事务中只能查看不能增删改 +> ```mysql +> start transaction read only;-- 创建只读事务 +``` + +# 作业 + +```sql +create table dept( + deptno int primary key auto_increment, -- 部门编号 + dname varchar(14) , -- 部门名字 + loc varchar(13) -- 地址 +) ; +-- 员工表 +create table emp( + empno int primary key auto_increment,-- 员工编号 + ename varchar(10), -- 员工姓名 - + job varchar(9), -- 岗位 + mgr int, -- 直接领导编号 + hiredate date, -- 雇佣日期,入职日期 + sal int, -- 薪水 + comm int, -- 提成 + deptno int not null, -- 部门编号 + foreign key (deptno) references dept(deptno) +); +insert into dept values(10,'财务部','北京'); +insert into dept values(20,'研发部','上海'); +insert into dept values(30,'销售部','广州'); +insert into dept values(40,'行政部','深圳'); +insert into emp values(7369,'刘一','职员',7902,'1980-12-17',800,null,20); +insert into emp values(7499,'陈二','推销员',7698,'1981-02-20',1600,300,30); +insert into emp values(7521,'张三','推销员',7698,'1981-02-22',1250,500,30); +insert into emp values(7566,'李四','经理',7839,'1981-04-02',2975,null,20); +insert into emp values(7654,'王五','推销员',7698,'1981-09-28',1250,1400,30); +insert into emp values(7698,'赵六','经理',7839,'1981-05-01',2850,null,30); +insert into emp values(7782,'孙七','经理',7839,'1981-06-09',2450,null,10); +insert into emp values(7788,'周八','分析师',7566,'1987-06-13',3000,null,20); +insert into emp values(7839,'吴九','总裁',null,'1981-11-17',5000,null,10); +insert into emp values(7844,'郑十','推销员',7698,'1981-09-08',1500,0,30); +insert into emp values(7876,'郭十一','职员',7788,'1987-06-13',1100,null,20); +insert into emp values(7900,'钱多多','职员',7698,'1981-12-03',950,null,30); +insert into emp values(7902,'大锦鲤','分析师',7566,'1981-12-03',3000,null,20); +insert into emp values(7934,'木有钱','职员',7782,'1983-01-23',1300,null,10); +# 完成以下练习题 +# +# 1、列出最低薪金大于1500的各种工作。 +select job,sal+ifnull(comm,0) from emp where sal+ifnull(comm,0)>1500 ; +select job,max(sal) from emp group by job having max(sal)>1500; +# 2、列出在部门 "销售部" 工作的员工的姓名,假定不知道销售部的部门编号。 +select ename,deptno from emp where deptno=(select deptno from dept where dname='销售部'); +# 3、列出薪金高于公司平均薪金的所有员工。 +select ename,sal from emp where sal>2073; +select avg(sal) from emp; +SELECT ename FROM ( +SELECT ename,sal>avg(sal) over() AS high FROM emp) a WHERE high=1; +# 4、列出与"周八"从事相同工作的所有员工。 +select * from emp where job=( +select job from emp where ename='周八'); +#5、列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金。 +select ename,sal from emp inner join dept d on emp.deptno = d.deptno where d.deptno=30; + +# 6、列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。 +SELECT ename,sal FROM emp WHERE sal >( +SELECT max(sal) FROM emp WHERE deptno=30 GROUP BY deptno); +# 7、列出在每个部门工作的员工数量、平均工资、平均服务年限。 +select d.dname 部门,count(e.ename) 员工数量,avg(e.sal) 平均工资,avg(year(now())-year(hiredate)) 平均服务年限 from emp e RIGHT JOIN dept d ON e.deptno=d.deptno GROUP BY d.dname; +# 8、列出所有员工的姓名、部门名称和工资。 +SELECT e.ename 姓名,d.dname 部门名称,e.sal 工资 FROM emp e INNER JOIN dept d on e.deptno=d.deptno; +# 9、列出所有部门的详细信息和部门人数。 +SELECT distinct d.*,COUNT(e.deptno) over (PARTITION BY e.deptno) 员工数量 FROM emp e RIGHT JOIN dept d ON e.deptno=d.deptno; +# 10、列出各种工作的最低工资。 +select distinct job,min(sal) over (partition by job) from emp; +# 11、列出各个部门的 经理 的最低薪金。 +select distinct d.* ,min(e.sal) over (partition by sal) from emp e right join dept d on d.deptno = e.deptno where job='经理'; +# 12、列出所有员工的年工资,按年薪从低到高排序。 +SELECT ename,sal*12+IFNULL(comm,0) FROM emp ORDER BY sal*12+IFNULL(comm,0); +``` \ No newline at end of file