From 79c60f0b340562fe118bf91d4f92393e81dea850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=84=E7=8F=8A=E7=8F=8A?= <3106036048@qq.com> Date: Fri, 20 Oct 2023 11:05:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...12\351\242\230\347\273\203\344\271\240.md" | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 "48 \345\272\204\347\217\212\347\217\212/20231019 \344\272\213\345\212\241\344\273\245\345\217\212sql12\351\242\230\347\273\203\344\271\240.md" diff --git "a/48 \345\272\204\347\217\212\347\217\212/20231019 \344\272\213\345\212\241\344\273\245\345\217\212sql12\351\242\230\347\273\203\344\271\240.md" "b/48 \345\272\204\347\217\212\347\217\212/20231019 \344\272\213\345\212\241\344\273\245\345\217\212sql12\351\242\230\347\273\203\344\271\240.md" new file mode 100644 index 0000000..fdd15f4 --- /dev/null +++ "b/48 \345\272\204\347\217\212\347\217\212/20231019 \344\272\213\345\212\241\344\273\245\345\217\212sql12\351\242\230\347\273\203\344\271\240.md" @@ -0,0 +1,217 @@ +# 笔记 + +## 1.事务: + +特点: + +1.原子性:事务已经是最小单位了,不可能会比事务更小 + +事务是将多条sql语句捆绑一起执行的要么一起成功要么一起失败 + +2.一致性:数据从a到b一定要一致,同时状态也要一致 + +3.隔离性:两个事务之间,事务a与事务b之间有一个隔离墙 + +4.持久性:事务一旦提交,对数据库的更改时永久性的 + +事务的操作: + +事务的操作: + +事务一开始为隐式事务,是自动提交的,所以我们要手动打开它,代码如下: + +```mysql +set autocommit=0;-- 手动提交事务 +set autocommit=off; +``` + +提交事务的代码如下: + +```mysql +start transaction; -- 开启事务 +create table test1(id int);-- 建表语句 +set autocommit=0;-- 手动提交事务 +insert into test1 values(1);-- 插入一条数据的sql语句 +commit;-- 提交事务!!(提交之后将关闭事务) +``` + +将事务提交后悔时可以使用回滚事务,代码如下: + +```mysql +start transaction; -- 开启事务 +create table test1(id int);-- 建表语句 +set autocommit=0;-- 手动提交事务 +insert into test1 values(1);-- 插入一条数据的sql语句 +rollback;-- 回滚数据将事务内这条插入语句回滚回刚开始的数据(回滚后也会关闭事务) +``` + +savepoint关键字的作用是当我们只想回滚部分数据是可以用它来实现,它就相当于一个存档,通过回滚指令来读档,代码如下: + +```mysql +start transaction; -- 开启事务 +create table test1(id int);-- 建表语句 +set autocommit=0;-- 手动提交事务 +insert into test1 values(1);-- 插入一条数据的sql语句 +savepoint a1;-- 在此处建立一个存档a1 +insert into test1 values(2);-- 插入第二条数据的sql语句 +savepoint a2; -- 在此处建立一个存档a2 +-- 当我们只想回滚到a2的操作时就可以用到这个存档了 +rollback to a2; +``` + +对于事务中的一些问题 + +### 脏读:我写了错误答案,同桌b抄了我的错误答案上交了,而我在上交前把错误答案修改成正确答案 + +### 读已提交:同桌b可以看到所有已提交的答案进行操作 + +(这种情况发生 在一个事务内多次读同一数据。A事务查询某条数据,**该事务未结束时**,**B事务也访问同一数据并进行了修改**。那么在A事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。) + +### 可重复读 + +一个事务操作中对于一个读取操作不管多少次,读取到的结果都是一样的。 + +### 幻读 + +脏读、不可重复读、可重复读、幻读,其中最难理解的是幻读。 + +全部结合就是它 + +# 作业 + +## 1.sql十二题练习 + +```mysql +-- 部门表 +create database tb12 charset utf8; +use tb12; +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的各种工作。 +with a as +(select job, min(sal) 最低薪资 from emp group by job) +select * from a where 最低薪资>1500; +# 2、列出在部门 "销售部" 工作的员工的姓名,假定不知道销售部的部门编号。 +with a as +(select dname,deptno from dept where dname='销售部'), +b as (select ename,deptno from emp) +select dname,ename,a.deptno from a left join b on a.deptno=b.deptno; +# 3、列出薪金高于公司平均薪金的所有员工。 +with a as +(select ename,sal,avg(sal) over () 平均工资 from emp) +select ename,sal,平均工资 from a where 平均工资 any(select sal from a); +# 7、列出在每个部门工作的员工数量、平均工资、平均服务年限。 +with a as +(select deptno,count(ename) 员工数量 ,avg(sal) 平均工资,avg(datediff(now(),hiredate)/365) 平均服务年限 from emp group by deptno) +select d.deptno,a.员工数量,a.平均工资,a.平均服务年限 from dept d inner join a on d.deptno = a.deptno; ; +# 8、列出所有员工的姓名、部门名称和工资。 +with a as ( select ename,sal,deptno from emp), +b as ( select dname,deptno from dept) +select ename,dname,sal from a left join b on a.deptno=b.deptno; +# 9、列出所有部门的详细信息和部门人数。 +with a as( +select deptno,count(*)部门人数 from emp group by deptno) +select dept.*,部门人数 from dept left join a on dept.deptno = a.deptno; +# 10、列出各种工作的最低工资。 +with a as( +select job,min(sal) 最低工资 from emp group by job) +select job,最低工资 from a; +# 11、列出各个部门的 经理 的最低薪金。 +with a as ( +select deptno,min(sal) 最低薪金 from emp where job='经理' group by deptno) +select a.deptno,dname,最低薪金,e.ename,e.job from a inner join dept on a.deptno=dept.deptno inner join emp e on dept.deptno = e.deptno and e.job='经理' and e.sal=a.最低薪金; +# 12、列出所有员工的年工资,按年薪从低到高排序。 +select ename,sal*12 年薪,rank() over (order by sal*12) from emp; +``` + +## 2.利用事务插表 + + + +```mysql +START TRANSACTION; + +-- 设置插入数据的数量 +SET @insert_count = 10000000; +SET @batch_size = 1000; -- 每批次插入的数量 + +-- 创建临时表来存储待插入的数据 +CREATE TEMPORARY TABLE temp_data ( + id INT, + name VARCHAR(50) +); + +-- 循环插入数据 +SET @i = 1; +WHILE @i <= @insert_count DO + -- 开始批处理 + START TRANSACTION; + +-- 清空临时表 +TRUNCATE TABLE temp_data; + +-- 生成插入数据,并将其插入临时表 +SET @j = 0; +WHILE @j < @batch_size DO + INSERT INTO temp_data (id, name) VALUES (@i + @j, CONCAT('Name', @i + @j)); + SET @j = @j + 1; +END WHILE; + +-- 将临时表数据插入目标表 +INSERT INTO target_table (id, name) +SELECT id, name FROM temp_data; + +-- 提交事务 +COMMIT; + +SET @i = @i + @batch_size; +END WHILE; + +COMMIT; +``` -- Gitee