From 214c0708961acc645738482dc926e7c41648f545 Mon Sep 17 00:00:00 2001 From: unknown <2152890632@qq.com> Date: Fri, 20 Oct 2023 01:03:58 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E7=B4=A2=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20231018.md" | 83 ++++++ .../20231019.md" | 255 ++++++++++++++++++ 2 files changed, 338 insertions(+) create mode 100644 "06 \351\231\210\345\277\227\344\274\237/20231018.md" create mode 100644 "06 \351\231\210\345\277\227\344\274\237/20231019.md" diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231018.md" "b/06 \351\231\210\345\277\227\344\274\237/20231018.md" new file mode 100644 index 0000000..f97c072 --- /dev/null +++ "b/06 \351\231\210\345\277\227\344\274\237/20231018.md" @@ -0,0 +1,83 @@ +## 补充 + +### timestampdiff(单位,a,b) + +``` +单位:year、month、day、hour、minute、second、miscrosecond +a为小 +b为大 +向下取整,满24小时为一天 +``` + +## 索引预习笔记 + +索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。 + +#### 索引优点 + +1. 索引大大减小了服务器需要扫描的数据量,从而大大加快数据的检索速度,这也是创建索引的最主要的原因。 +2. 索引可以帮助服务器避免排序和创建临时表 +3. 索引可以将随机IO变成顺序IO +4. 索引对于InnoDB(对索引支持行级锁)非常重要,因为它可以让查询锁更少的元组,提高了表访问并发性 +5. 关于InnoDB、索引和锁:InnoDB在二级索引上使用共享锁(读锁),但访问主键索引需要排他锁(写锁) +6. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 +7. 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 +8. 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 +9. 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 + +#### 索引缺点 + +1. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加 +2. 索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间,如果需要建立聚簇索引,那么需要占用的空间会更大 +3. 对表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度 +4. 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。 +5. 对于非常小的表,大部分情况下简单的全表扫描更高效; + +#### 创建索引准则 + +索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。 + +##### 应该创建索引的列 + +1. 在经常需要搜索的列上,可以加快搜索的速度 +2. 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构 +3. 在经常用在连接(JOIN)的列上,这些列主要是一外键,可以加快连接的速度 +4. 在经常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的 +5. 在经常需要排序(order by)的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; +6. 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 + +##### 不该创建索引的列 + +- 对于那些在查询中很少使用或者参考的列不应该创建索引。 +- 若列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 +- 对于那些只有很少数据值或者重复值多的列也不应该增加索引。 +- 这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 +- 对于那些定义为text, image和bit数据类型的列不应该增加索引。 +- 这些列的数据量要么相当大,要么取值很少。 +- 当该列修改性能要求远远高于检索性能时,不应该创建索引。(修改性能和检索性能是互相矛盾的) + +#### 索引语法 + +##### 索引分类 + +- 主键索引 不允许重复,不允许为null + +~~~mysql + ALTER TABLE TableName ADD PRIMARY KEY(column_list); +~~~ + +- 唯一索引 数据列不允许重复,允许为 NULL 值,一张表可有多个唯一索引,索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。 + +~~~mysql +CREATE UNIQUE INDEX IndexName ON `TableName`(`字段名`(length)); +# 或者 +ALTER TABLE TableName ADD UNIQUE (column_list); +~~~ + +- 普通索引:一张表可以创建多个普通索引,一个普通索引可以包含多个字段,允许数据重复,允许 NULL 值插入; + +~~~mysql +CREATE INDEX IndexName ON `TableName`(`字段名`(length)); +# 或者 +ALTER TABLE TableName ADD INDEX IndexName(`字段名`(length)); +~~~ \ No newline at end of file diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231019.md" "b/06 \351\231\210\345\277\227\344\274\237/20231019.md" new file mode 100644 index 0000000..a9155d0 --- /dev/null +++ "b/06 \351\231\210\345\277\227\344\274\237/20231019.md" @@ -0,0 +1,255 @@ +## 索引 + +索引(index)是帮助MySQL高效获取数据的数据结构 + +#### 优点 + +降低CPU的消耗 + +#### 缺点 + + 降低了 INSERT、UPDATE、DELETE 速度 + +### 索引的分类 + +单列索引:一个索引建立在一个列上,一张表可以拥有多个单列索引 + +- 普通索引:单纯地为了提高搜索效率 index +- 唯一索引:unique index,唯一索引只能够建立在数据不重复的列上 ,唯一约束 ,不能重复,可以null,有多个唯一索引 +- 主键索引:primary key唯一性、非空,主键约束 ,不能重复,也不能null,一个只能有一个主键 + +联合索引:可以同时为多个列创建一个索引 + +### 单列索引 + +#### 创建索引(普通索引) + +这是最基本的索引,它没有任何限制。它有以下几种创建方式: + +方式一:直接在已有表中创建索引 + +```sql +create index 索引名 on 表名(列名) -- 直接删除索引 drop index 索引名 on 表名; 这种不能用来创建主键索引 +``` + +方式二:修改表结构追加普通索引 + +```sql +alter table 表名 add index 索引名(列名); -- 修改表结构删除索引 alter table 表名 drop index 索引名; +``` + +方式三:创建表的时候直接指定 + +```sql +create table 表名( + aaa int primary key, + bbb varchar(20), + index 索引名 (列名) -- 以这种模式定义的索引,可以不指定索引名称。 + primary key(列名) +); +``` + +#### 查看表的索引 + +```sql +show index from 表名; +``` + +可以查看到创建在表上的所有索引名称。 + +#### 删除索引 + +```sql +drop index 索引名 on 表名; +``` + +并且删除表时,会一并删除表上的全部索引。 + +```sql +alter table 表名 drop index 索引名; +``` + +#### 唯一索引:建立列的唯一约束时,会自动创建唯一的索引,索引名就是列名 + +它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式 + +```mysql +create unique index 索引名 on 表名(列名); -- 创建普通索引的基础上。多了unique关键字 +``` + + 在已存在的表上追加唯一索引 + +```mysql +alter table 表名 add unique 索引名 (列名) +``` + + 创建表的时候直接指定 + +```mysql +create table tc_9( + aaa int primary key, + bbb varchar(20), + unique [INDEX] 索引名 (列名) -- 唯一索引,一定有索引名,index 可以省略 +); + +-- 唯一索引和唯一约束 语法还是 有些区别 +create table tc_9( + aaa int primary key, + bbb varchar(20), + tel char(11), -- unique not null, + unique (tel) -- unique(列名) -- 约束是没有 索引名 和 index 关键字的 +); +``` + +**删除唯一索引的方法与删除普通索引相同。** + + +#### 主键索引 与 index 关键字没有关系 + +主键索引:它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候指定了主键,就会创建主键索引, CREATE INDEX不能用来创建主键索引,使用 ALTER TABLE来代替。 + +创建主键索引,就是创建主键约束 + +```sql +drop table if exists tc_10; +create table tc_10( + aaa int primary key, + bbb varchar(20), + ccc datetime +); +create table tc_10( + aaa int, + bbb varchar(20), + ccc datetime, + primary key(aaa) +); +create table tc_10( + aaa int, + bbb varchar(20), + ccc datetime +); +alter table tc_10 add primary key(aaa); +``` + +删除主键 + +可以使用 ALTER 命令删除主键: index + +```sql +alter table 表名 drop primary key; +``` + +删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。而不能使用删除普通索引的方法来删除主键索引。 + +```sql +-- 这都是错误的。 +drop index PRIMARY on tc_10; +drop primary key on tc_10; +``` + +### 联合索引 + +```sql +create index 索引名 on 表名(列名1,列名2....) -- 普通的联合索引 +create unique index 索引名 on 表名(列名1,列名2....) -- 联合唯一索引 +``` + +*执行原则:最左前缀法则 + +如果使用了联合索引,要遵守最左前缀法则。 + +最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,后面的字段索引失效。 + +## 作业 + +执行查询文件tb_user.sql,数据准备好了之后,完成如下需求: + +```mysql +-- 1.name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。 + +create index inx_name on tb_user(`name`); + +show index from tb_user; + +explain select `name` from tb_user; + +-- 2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。 + +create unique index inx_phone on tb_user(phone); + +show index from tb_user; + +explain select phone from tb_user; + +-- 3. 为profession、age、status创建联合索引。 + +create index inx_user on tb_user(profession,age,`status`); + +show index from tb_user; + +explain select profession,age,`status` from tb_user; + +-- 4. 为email建立合适的索引来提升查询效率。 + +create index inx_email on tb_user(email); + +show index from tb_user; + +explain select email from tb_user; + +-- 5. 查看tb_user表的所有的索引数据。 + +show index from tb_user; +``` + +```mysql +delimiter // +create procedure pro_v() +begin + declare i int default 1; + start transaction; + while i<=100000 do + insert into zen values(null,(select concat + (mid('文徐李悠金郑钱黄肖罗将刘钟朴沈梁西林纱名平周方韩张章',floor(rand()*26+1),1), + substr('龙铉维知志多礼夏井子元采一泰太辰成在廷昇祯精彩宥',floor(rand()*24+1),1), + substr('馥辰志浩娜桃南一容祐英月喻元寅玟源叶演领',floor(rand()*20+1),1))), + (select mid('男女',floor(rand()*2+1),1)), + (select 100+i), + (select '爱好')); + set i=i+1; + end while; + commit; +end // + +call pro_v(); + +``` + +```mysql +use biao; +create table emlopyee( + id int primary key auto_increment, + namc char(3), + sex char(1) +); +drop procedure nam; +delimiter // + create procedure nam() + begin + declare i int default 0; + declare a varchar(3); + declare b varchar(1); + while i < 10 do + set a= CONCAT( +substring('赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳',floor(rand()*60+1),1), +substring('伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛',rand()*139+1,1), +substring('伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛',rand()*139+1,1)); + set b= substring('男女',floor(rand()*2+1),1); + insert into emlopyee values(null,a,b); + set i= i+1; + end while; + end // +delimiter; +call nam(); +``` + -- Gitee From 17851a74742ca28a5f653b1ae259224bf9bb1e73 Mon Sep 17 00:00:00 2001 From: unknown <2152890632@qq.com> Date: Fri, 20 Oct 2023 01:08:03 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E7=B4=A2=E5=BC=95=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20231018.md" | 290 ++++++++++++++---- .../20231019.md" | 255 --------------- 2 files changed, 231 insertions(+), 314 deletions(-) delete mode 100644 "06 \351\231\210\345\277\227\344\274\237/20231019.md" diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231018.md" "b/06 \351\231\210\345\277\227\344\274\237/20231018.md" index f97c072..a9155d0 100644 --- "a/06 \351\231\210\345\277\227\344\274\237/20231018.md" +++ "b/06 \351\231\210\345\277\227\344\274\237/20231018.md" @@ -1,83 +1,255 @@ -## 补充 +## 索引 -### timestampdiff(单位,a,b) +索引(index)是帮助MySQL高效获取数据的数据结构 +#### 优点 + +降低CPU的消耗 + +#### 缺点 + + 降低了 INSERT、UPDATE、DELETE 速度 + +### 索引的分类 + +单列索引:一个索引建立在一个列上,一张表可以拥有多个单列索引 + +- 普通索引:单纯地为了提高搜索效率 index +- 唯一索引:unique index,唯一索引只能够建立在数据不重复的列上 ,唯一约束 ,不能重复,可以null,有多个唯一索引 +- 主键索引:primary key唯一性、非空,主键约束 ,不能重复,也不能null,一个只能有一个主键 + +联合索引:可以同时为多个列创建一个索引 + +### 单列索引 + +#### 创建索引(普通索引) + +这是最基本的索引,它没有任何限制。它有以下几种创建方式: + +方式一:直接在已有表中创建索引 + +```sql +create index 索引名 on 表名(列名) -- 直接删除索引 drop index 索引名 on 表名; 这种不能用来创建主键索引 +``` + +方式二:修改表结构追加普通索引 + +```sql +alter table 表名 add index 索引名(列名); -- 修改表结构删除索引 alter table 表名 drop index 索引名; +``` + +方式三:创建表的时候直接指定 + +```sql +create table 表名( + aaa int primary key, + bbb varchar(20), + index 索引名 (列名) -- 以这种模式定义的索引,可以不指定索引名称。 + primary key(列名) +); +``` + +#### 查看表的索引 + +```sql +show index from 表名; +``` + +可以查看到创建在表上的所有索引名称。 + +#### 删除索引 + +```sql +drop index 索引名 on 表名; +``` + +并且删除表时,会一并删除表上的全部索引。 + +```sql +alter table 表名 drop index 索引名; +``` + +#### 唯一索引:建立列的唯一约束时,会自动创建唯一的索引,索引名就是列名 + +它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式 + +```mysql +create unique index 索引名 on 表名(列名); -- 创建普通索引的基础上。多了unique关键字 +``` + + 在已存在的表上追加唯一索引 + +```mysql +alter table 表名 add unique 索引名 (列名) ``` -单位:year、month、day、hour、minute、second、miscrosecond -a为小 -b为大 -向下取整,满24小时为一天 + + 创建表的时候直接指定 + +```mysql +create table tc_9( + aaa int primary key, + bbb varchar(20), + unique [INDEX] 索引名 (列名) -- 唯一索引,一定有索引名,index 可以省略 +); + +-- 唯一索引和唯一约束 语法还是 有些区别 +create table tc_9( + aaa int primary key, + bbb varchar(20), + tel char(11), -- unique not null, + unique (tel) -- unique(列名) -- 约束是没有 索引名 和 index 关键字的 +); ``` -## 索引预习笔记 +**删除唯一索引的方法与删除普通索引相同。** + + +#### 主键索引 与 index 关键字没有关系 + +主键索引:它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候指定了主键,就会创建主键索引, CREATE INDEX不能用来创建主键索引,使用 ALTER TABLE来代替。 + +创建主键索引,就是创建主键约束 + +```sql +drop table if exists tc_10; +create table tc_10( + aaa int primary key, + bbb varchar(20), + ccc datetime +); +create table tc_10( + aaa int, + bbb varchar(20), + ccc datetime, + primary key(aaa) +); +create table tc_10( + aaa int, + bbb varchar(20), + ccc datetime +); +alter table tc_10 add primary key(aaa); +``` -索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。 +删除主键 -#### 索引优点 +可以使用 ALTER 命令删除主键: index -1. 索引大大减小了服务器需要扫描的数据量,从而大大加快数据的检索速度,这也是创建索引的最主要的原因。 -2. 索引可以帮助服务器避免排序和创建临时表 -3. 索引可以将随机IO变成顺序IO -4. 索引对于InnoDB(对索引支持行级锁)非常重要,因为它可以让查询锁更少的元组,提高了表访问并发性 -5. 关于InnoDB、索引和锁:InnoDB在二级索引上使用共享锁(读锁),但访问主键索引需要排他锁(写锁) -6. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 -7. 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 -8. 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 -9. 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 +```sql +alter table 表名 drop primary key; +``` + +删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。而不能使用删除普通索引的方法来删除主键索引。 + +```sql +-- 这都是错误的。 +drop index PRIMARY on tc_10; +drop primary key on tc_10; +``` + +### 联合索引 + +```sql +create index 索引名 on 表名(列名1,列名2....) -- 普通的联合索引 +create unique index 索引名 on 表名(列名1,列名2....) -- 联合唯一索引 +``` -#### 索引缺点 +*执行原则:最左前缀法则 -1. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加 -2. 索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间,如果需要建立聚簇索引,那么需要占用的空间会更大 -3. 对表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度 -4. 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。 -5. 对于非常小的表,大部分情况下简单的全表扫描更高效; +如果使用了联合索引,要遵守最左前缀法则。 -#### 创建索引准则 +最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,后面的字段索引失效。 -索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。 +## 作业 -##### 应该创建索引的列 +执行查询文件tb_user.sql,数据准备好了之后,完成如下需求: -1. 在经常需要搜索的列上,可以加快搜索的速度 -2. 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构 -3. 在经常用在连接(JOIN)的列上,这些列主要是一外键,可以加快连接的速度 -4. 在经常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的 -5. 在经常需要排序(order by)的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; -6. 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 +```mysql +-- 1.name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。 -##### 不该创建索引的列 +create index inx_name on tb_user(`name`); -- 对于那些在查询中很少使用或者参考的列不应该创建索引。 -- 若列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 -- 对于那些只有很少数据值或者重复值多的列也不应该增加索引。 -- 这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 -- 对于那些定义为text, image和bit数据类型的列不应该增加索引。 -- 这些列的数据量要么相当大,要么取值很少。 -- 当该列修改性能要求远远高于检索性能时,不应该创建索引。(修改性能和检索性能是互相矛盾的) +show index from tb_user; -#### 索引语法 +explain select `name` from tb_user; -##### 索引分类 +-- 2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。 -- 主键索引 不允许重复,不允许为null +create unique index inx_phone on tb_user(phone); -~~~mysql - ALTER TABLE TableName ADD PRIMARY KEY(column_list); -~~~ +show index from tb_user; -- 唯一索引 数据列不允许重复,允许为 NULL 值,一张表可有多个唯一索引,索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。 +explain select phone from tb_user; -~~~mysql -CREATE UNIQUE INDEX IndexName ON `TableName`(`字段名`(length)); -# 或者 -ALTER TABLE TableName ADD UNIQUE (column_list); -~~~ +-- 3. 为profession、age、status创建联合索引。 -- 普通索引:一张表可以创建多个普通索引,一个普通索引可以包含多个字段,允许数据重复,允许 NULL 值插入; +create index inx_user on tb_user(profession,age,`status`); + +show index from tb_user; + +explain select profession,age,`status` from tb_user; + +-- 4. 为email建立合适的索引来提升查询效率。 + +create index inx_email on tb_user(email); + +show index from tb_user; + +explain select email from tb_user; + +-- 5. 查看tb_user表的所有的索引数据。 + +show index from tb_user; +``` + +```mysql +delimiter // +create procedure pro_v() +begin + declare i int default 1; + start transaction; + while i<=100000 do + insert into zen values(null,(select concat + (mid('文徐李悠金郑钱黄肖罗将刘钟朴沈梁西林纱名平周方韩张章',floor(rand()*26+1),1), + substr('龙铉维知志多礼夏井子元采一泰太辰成在廷昇祯精彩宥',floor(rand()*24+1),1), + substr('馥辰志浩娜桃南一容祐英月喻元寅玟源叶演领',floor(rand()*20+1),1))), + (select mid('男女',floor(rand()*2+1),1)), + (select 100+i), + (select '爱好')); + set i=i+1; + end while; + commit; +end // + +call pro_v(); + +``` + +```mysql +use biao; +create table emlopyee( + id int primary key auto_increment, + namc char(3), + sex char(1) +); +drop procedure nam; +delimiter // + create procedure nam() + begin + declare i int default 0; + declare a varchar(3); + declare b varchar(1); + while i < 10 do + set a= CONCAT( +substring('赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳',floor(rand()*60+1),1), +substring('伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛',rand()*139+1,1), +substring('伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛',rand()*139+1,1)); + set b= substring('男女',floor(rand()*2+1),1); + insert into emlopyee values(null,a,b); + set i= i+1; + end while; + end // +delimiter; +call nam(); +``` -~~~mysql -CREATE INDEX IndexName ON `TableName`(`字段名`(length)); -# 或者 -ALTER TABLE TableName ADD INDEX IndexName(`字段名`(length)); -~~~ \ No newline at end of file diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231019.md" "b/06 \351\231\210\345\277\227\344\274\237/20231019.md" deleted file mode 100644 index a9155d0..0000000 --- "a/06 \351\231\210\345\277\227\344\274\237/20231019.md" +++ /dev/null @@ -1,255 +0,0 @@ -## 索引 - -索引(index)是帮助MySQL高效获取数据的数据结构 - -#### 优点 - -降低CPU的消耗 - -#### 缺点 - - 降低了 INSERT、UPDATE、DELETE 速度 - -### 索引的分类 - -单列索引:一个索引建立在一个列上,一张表可以拥有多个单列索引 - -- 普通索引:单纯地为了提高搜索效率 index -- 唯一索引:unique index,唯一索引只能够建立在数据不重复的列上 ,唯一约束 ,不能重复,可以null,有多个唯一索引 -- 主键索引:primary key唯一性、非空,主键约束 ,不能重复,也不能null,一个只能有一个主键 - -联合索引:可以同时为多个列创建一个索引 - -### 单列索引 - -#### 创建索引(普通索引) - -这是最基本的索引,它没有任何限制。它有以下几种创建方式: - -方式一:直接在已有表中创建索引 - -```sql -create index 索引名 on 表名(列名) -- 直接删除索引 drop index 索引名 on 表名; 这种不能用来创建主键索引 -``` - -方式二:修改表结构追加普通索引 - -```sql -alter table 表名 add index 索引名(列名); -- 修改表结构删除索引 alter table 表名 drop index 索引名; -``` - -方式三:创建表的时候直接指定 - -```sql -create table 表名( - aaa int primary key, - bbb varchar(20), - index 索引名 (列名) -- 以这种模式定义的索引,可以不指定索引名称。 - primary key(列名) -); -``` - -#### 查看表的索引 - -```sql -show index from 表名; -``` - -可以查看到创建在表上的所有索引名称。 - -#### 删除索引 - -```sql -drop index 索引名 on 表名; -``` - -并且删除表时,会一并删除表上的全部索引。 - -```sql -alter table 表名 drop index 索引名; -``` - -#### 唯一索引:建立列的唯一约束时,会自动创建唯一的索引,索引名就是列名 - -它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式 - -```mysql -create unique index 索引名 on 表名(列名); -- 创建普通索引的基础上。多了unique关键字 -``` - - 在已存在的表上追加唯一索引 - -```mysql -alter table 表名 add unique 索引名 (列名) -``` - - 创建表的时候直接指定 - -```mysql -create table tc_9( - aaa int primary key, - bbb varchar(20), - unique [INDEX] 索引名 (列名) -- 唯一索引,一定有索引名,index 可以省略 -); - --- 唯一索引和唯一约束 语法还是 有些区别 -create table tc_9( - aaa int primary key, - bbb varchar(20), - tel char(11), -- unique not null, - unique (tel) -- unique(列名) -- 约束是没有 索引名 和 index 关键字的 -); -``` - -**删除唯一索引的方法与删除普通索引相同。** - - -#### 主键索引 与 index 关键字没有关系 - -主键索引:它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候指定了主键,就会创建主键索引, CREATE INDEX不能用来创建主键索引,使用 ALTER TABLE来代替。 - -创建主键索引,就是创建主键约束 - -```sql -drop table if exists tc_10; -create table tc_10( - aaa int primary key, - bbb varchar(20), - ccc datetime -); -create table tc_10( - aaa int, - bbb varchar(20), - ccc datetime, - primary key(aaa) -); -create table tc_10( - aaa int, - bbb varchar(20), - ccc datetime -); -alter table tc_10 add primary key(aaa); -``` - -删除主键 - -可以使用 ALTER 命令删除主键: index - -```sql -alter table 表名 drop primary key; -``` - -删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。而不能使用删除普通索引的方法来删除主键索引。 - -```sql --- 这都是错误的。 -drop index PRIMARY on tc_10; -drop primary key on tc_10; -``` - -### 联合索引 - -```sql -create index 索引名 on 表名(列名1,列名2....) -- 普通的联合索引 -create unique index 索引名 on 表名(列名1,列名2....) -- 联合唯一索引 -``` - -*执行原则:最左前缀法则 - -如果使用了联合索引,要遵守最左前缀法则。 - -最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,后面的字段索引失效。 - -## 作业 - -执行查询文件tb_user.sql,数据准备好了之后,完成如下需求: - -```mysql --- 1.name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。 - -create index inx_name on tb_user(`name`); - -show index from tb_user; - -explain select `name` from tb_user; - --- 2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。 - -create unique index inx_phone on tb_user(phone); - -show index from tb_user; - -explain select phone from tb_user; - --- 3. 为profession、age、status创建联合索引。 - -create index inx_user on tb_user(profession,age,`status`); - -show index from tb_user; - -explain select profession,age,`status` from tb_user; - --- 4. 为email建立合适的索引来提升查询效率。 - -create index inx_email on tb_user(email); - -show index from tb_user; - -explain select email from tb_user; - --- 5. 查看tb_user表的所有的索引数据。 - -show index from tb_user; -``` - -```mysql -delimiter // -create procedure pro_v() -begin - declare i int default 1; - start transaction; - while i<=100000 do - insert into zen values(null,(select concat - (mid('文徐李悠金郑钱黄肖罗将刘钟朴沈梁西林纱名平周方韩张章',floor(rand()*26+1),1), - substr('龙铉维知志多礼夏井子元采一泰太辰成在廷昇祯精彩宥',floor(rand()*24+1),1), - substr('馥辰志浩娜桃南一容祐英月喻元寅玟源叶演领',floor(rand()*20+1),1))), - (select mid('男女',floor(rand()*2+1),1)), - (select 100+i), - (select '爱好')); - set i=i+1; - end while; - commit; -end // - -call pro_v(); - -``` - -```mysql -use biao; -create table emlopyee( - id int primary key auto_increment, - namc char(3), - sex char(1) -); -drop procedure nam; -delimiter // - create procedure nam() - begin - declare i int default 0; - declare a varchar(3); - declare b varchar(1); - while i < 10 do - set a= CONCAT( -substring('赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳',floor(rand()*60+1),1), -substring('伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛',rand()*139+1,1), -substring('伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞彬富顺信子杰涛昌成康星光天达安岩茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛',rand()*139+1,1)); - set b= substring('男女',floor(rand()*2+1),1); - insert into emlopyee values(null,a,b); - set i= i+1; - end while; - end // -delimiter; -call nam(); -``` - -- Gitee From 05a45db6f9f4ee2f4b841adfff70875b5025d3fd Mon Sep 17 00:00:00 2001 From: unknown <2152890632@qq.com> Date: Fri, 20 Oct 2023 01:10:09 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20231019.md" | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 "06 \351\231\210\345\277\227\344\274\237/20231019.md" diff --git "a/06 \351\231\210\345\277\227\344\274\237/20231019.md" "b/06 \351\231\210\345\277\227\344\274\237/20231019.md" new file mode 100644 index 0000000..a4bd8b2 --- /dev/null +++ "b/06 \351\231\210\345\277\227\344\274\237/20231019.md" @@ -0,0 +1,173 @@ +## 事务 + +### 事务的特性 + +原子性、一致性、隔离性、持久性 + +### 事务操作 + +mysql中事务默认是隐式事务,执行insert、update、delete操作的时候,数据库自动开启事务、提交或回滚事务 + +是否开启隐式事务是由变量autocommit控制的 + +所以事务分为**隐式事务**和**显式事务** + +#### 隐式事务 + +事务自动开启、提交或回滚,比如insert、update、delete语句,事务的开启、提交或回滚由mysql内部自动控制的。 + +查看变量autocommit是否开启了自动提交 + +#### 显式事务 + +事务需要手动开启、提交或回滚,由开发者自己控制。 + +```mysql +-- 显示所有的系统变量 +show variables; + +-- 查看autocommit状态 +show variables like 'autocommit'; + +-- 显式事务(手动提交,关闭系统自动) +set autocommit=off; +set autocommit=0; + +rollback; -- 撤销,可以保留数据 +commit; -- 提交数据 + +-- 隐式事务(自动提交,开启系统自动) +set autocommit=on; +set autocommit=1; + +rollback; -- 撤销,不保留数据,因为系统已经自动commit +``` + +```mysql +-- 开启事务 +start transaction; +-- 结束事务 +rollback / commit; +``` + +### savepoint关键字 + +可以将一大批操作分为几个部分,然后指定回滚某个部分。 + +```mysql +-- 在事务中途使用 +savepoint 保存名; + +-- 追溯回去 +rollback to 保存名; +``` + +### 只读事务 + +表示在事务中执行的是一些只读操作,如查询,但是不会做insert、update、delete操作,数据库内部对只读事务可能会有一些性能上的优化 + +```mysql +start transaction read only; +``` + +#### 脏读 + +#### 读已提交 + +#### 可重复读 + +#### 幻读 + +### 隔离级别 + +隔离级别分为4种: + +```mysql +读未提交:READ-UNCOMMITTED +读已提交:READ-COMMITTED +可重复读:REPEATABLE-READ +串行:SERIALIZABLE +``` + + + +## 作业 + +```mysql +-- 部门表 +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 distinct job from emp where sal > 1500; +-- 2、列出在部门 "销售部" 工作的员工的姓名,假定不知道销售部的部门编号。 +-- +select * from emp where (deptno not in(10,20,40)); +-- 3、列出薪金高于公司平均薪金的所有员工。 +-- +select * from emp where sal > (select avg(sal) from emp); +-- 4、列出与"周八"从事相同工作的所有员工。 +-- +select * from emp where job = ( +select job from emp where ename = '周八') and ename != '周八'; +-- 5、列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金。 +-- +SELECT * from emp where sal in +(select sal from emp where deptno = 30); +-- 6、列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。 +-- +select * from emp where sal> +(select max(sal) from emp where deptno = 30); +-- 7、列出在每个部门工作的员工数量、平均工资、平均服务年限。 +-- +select count(ename),avg(sal),avg(timestampdiff(year,hiredate,now())) from emp group by deptno; +-- 8、列出所有员工的姓名、部门名称和工资。 +-- +select ename,job,sal,dname from emp e,dept d where e.deptno=d.deptno; +-- 9、列出所有部门的详细信息和部门人数。 +-- +select distinct dname,loc,count(*) over(partition by dname) from emp e,dept d where e.deptno=d.deptno; +-- 10、列出各种工作的最低工资。 +-- +select min(sal) from emp group by deptno; +-- 11、列出各个部门的 经理 的最低薪金。 +-- +select min(sal) from emp where job = '经理' group by deptno; +-- 12、列出所有员工的年工资,按年薪从低到高排序。 +-- +select *,(sal+ifnull(comm,0))*365 a from emp ORDER BY a asc; +``` \ No newline at end of file -- Gitee