MySQL学习记录 【基本操作 → 数据操作 → 高级查询 → 联合查询】 总结

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

– ⼀次添加⼀条

insert into table_name(‘指定列1’,‘指定列2’…) values(‘字段1’,‘字段2’…);

– ⼀次添加多条

insert into table_name(‘指定列1’,‘指定列2’…) values(‘字段1’,‘字段2’…),(‘字段1’,‘字段2’…)…;

扩展:表和表数据的存储⽬录:show variables like '%dir%';,也可以使用:select @@datadir;

在这里插入图片描述

查询(Retrieve)
  1. 全列查询

select * from table_name;

开发环境使用较多(因为开发环境的数据一般不大),但在生产环境一定要慎用!

全列查询的缺点:

1.如果数据量大,会消耗很大的带宽信息,并且传输的速度会很慢 2.可能会影响索引的使用!

  1. 指定列查询

select 列名1,列名2 from table_name;

  1. 表达式查询

– eg:计算每个⼈的总成绩:

select name,chinese+math+english from score;

– eg:将所有数学成绩 + 10 分:

select name,math+10 from score;

使⽤ select 进⾏的表达式计算不会修改原表数据。

  1. 使⽤别名查询

– eg:计算成绩总和,列名命名为 total

select chinese+math+english as total from score;

  1. 去重 distinct

select distinct columns from table_name;

– 数学成绩去重:

select distinct math from score;

– 多⾏去重,语⽂+数据重复的才会合并:

select distinct chinese,math from score;

distinct 只能放在查询的最前⾯,distinct 错误⽤法:

select name,distinct math from score;

  1. 排序 order by → 升序(从小到大) asc / 降序(从大到小) asc/desc

sleect * from 表名 order by 列名,列名 asc/desc;

– 如果不指定asc/desc排序规则,那么默认情况下使用的就是升序的排序规则

– eg:总分排名:

selsct name,(math+chinese+english) as ‘总分’ from score orger by (math+chinese+english) desc;

– NULL 列为最⼩值

– 多列排序:

order by 列1,列2 asc/desc;

  1. 条件查询

比较运算符

在这里插入图片描述

逻辑运算符

在这里插入图片描述

注:

· where条件可以使用表达式,但不能使用别名

· and的优先级高于or,在同时使用时,需要使用小括号()包裹优先执行的部分。

面试问题:为什么别名不能使用在where中,而可以使用在order by中?

在这里插入图片描述

别名是在第五步select 才产生的,在第二步where中不能使用。

  • 基本查询

– 查询英语不及格的同学及英语成绩 ( < 60 )

select name, english from exam_result where english < 60;

– 查询语文成绩好于英语成绩的同学

select name, chinese, english from exam_result where chinese > english;

– 查询总分在 200 分以下的同学

select name, chinese + math + english 总分 from exam_result

where chinese + math + english < 200;

  • AND与OR:

– 查询语文成绩大于80分,且英语成绩大于80分的同学

select * from exam_result where chinese > 80 and english > 80;

– 查询语文成绩大于80分,或英语成绩大于80分的同学

select * from exam_result where chinese > 80 or english > 80;

– 观察AND 和 OR 的优先级:

select * from exam_result where chinese > 80 or math>70 and english > 70;

select * from exam_result where (chinese > 80 or math>70) and english > 70;

– 查询语文成绩在 [80, 90] 分的同学及语文成绩

select name, chinese from exam_result where chinese between 80 and 90;

– 使用 AND 也可以实现

select name, chinese from exam_result where chinese >= 80 and chinese <= 90;

  • 范围查询

① between x and y

包含x和y

– 查询语文成绩在 [80, 90] 分的同学及语文成绩

select name, chinese from exam_result where chinese between 80 and 90;

– 使用 AND 也可以实现

select name, chinese from exam_result where chinese >= 80 and chinese <= 90;

② in

– 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩

select name, math from exam_result where math in(58, 59, 98, 99);

– 使用 OR 也可以实现

select name, math from exam_result where math = 58 or math = 59 or math = 98 or math = 99;

③ 模糊查询:like

– % 匹配任意多个(包括 0 个)字符

select name from exam_result where name like ‘孙%’;-- 匹配到孙悟空、孙权

– _ 匹配严格的一个任意字符

select name from exam_result where name like ‘孙_’;-- 匹配到孙权

④ null 查询

– 查询 qq_mail 已知的同学姓名

select name, qq_mail from student where qq_mail is not null;

– 查询 qq_mail 未知的同学姓名

select name, qq_mail from student where qq_mail is null;

  1. 分页查询:limit

查询某一个页面的部分信息(截取了部分行信息)。

– 起始下标为 0

– 从 0 开始,筛选 n 条结果

select… from table_name [where…] [order by …] limit n;

– 从 s 开始,筛选 n 条结果

select… from table_name [where…] [order by …] limit s, n;

– 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用

select… from table_name [where…] [order by …] limit n offset s;

– eg:

– 总分数排名前三

select name,chinese+math+english as total from score order by total desc limit 3;

– 总分数第⼆⻚(4-6条数据)

select name,chinese+math+english as total from score order by total desc limit 3 offset 3;

– limit x offset y(x,y 值超出不报错)

select name,chinese+math+english as total from score order by total desc limit 1000 offset 100;

修改(Update)

update table_name set column = expr [, column = expr …][where…] [order by …] [limit…]

– 1.全部修改

update score set math=85

– 2.部分修改

update score set math=85 where name=‘刘备’;

– 3.修改多列

update score set math=86,chinese=86 where name=‘刘备’;

– 4.表达式修改

– 全班倒数后 3 名成绩(按总成绩排名) +10 分

update score set math=math+10 order by math+chinese+english asc;

删除(Delete)

delete from table_name [where…] [order by …] [limit…]

– 1.删除单条

delete from score where name=‘刘备’;

– 2.全部删除 delete from score

– 3.清空表 truncate [table] 名称

扩充:

delete vs truncate

● truncate 删除快,但是数据不能被恢复;delete 删除慢,但数据能被恢复。

● delete 删除可以加条件,⽽ truncate 不能加条件。

delete 和 drop 的区别

● delete:只删除表中的数据。

● drop:删除表数据+表结构。

drop属于DDL,delete属于DML,而trucate属于DDL。

truvate执行原理:

① 拷贝一份原表结构进行创建

② 将原表进性删除和数据清除

delete执行原理

● 在InnoDB数据库引擎下,delete并不是真正的把数据删除掉了,而是给数据打了一个删除标签,标时当前的数据已经被删除了。数据存储大小不会改变。

● delete的数据是可以被恢复的,但是truncate、drop删除的数据是不能被恢复的。

● 执行效率:drop > truncate > delete

数据量越大,上面的执行效率差距也越大。

因为drop直接就删除掉表这个整体的结构就好了,truncate需要先把原表的结构拷贝一份,再删除原表结构,而delete是要去给数据打上删除标签的,他不能够快速直截了当的清除。

表约束和表设计—2

============================================================================

1. 什么是表约束


表约束是在创建表的时候,设计⼀些表的约束条件,⽤来保证数据的合法性和数据的正确性。

例如⼀个账号只能绑定⼀个⼿机号,那么⼿机号就不能重复,不能被多个账号绑定使⽤,所以它应该设 置唯⼀约束。⽽主键是⽤来标识数据的,因此它不能为 NULL,也不能为空,所以他需要设置⾮空约束 或(主键约束,主键约束也不能为 NULL)。

2. 为什么需要表约束?


就像法律是⽤来规范⼈们的正确行为的⼀样,表约束也是为了规范程序员正确使用表的,但表约束是预先设置的,设置之后就对所有插⼊和修改立即生效,比如非空约束设置好之后,如果添加和修改为 NULL 值就会报错,这点是和法律有细微的不同。

比如下表,如果对⽼师名称没有约束的话,那么数据 5 的这条⼯资就不能正常发放了,因为压根就不知道要发给谁:

总之如果没有表约束,会导致数据不正确,从而导致程序或现实中的业务⽆法推进和执行

3. 常见约束


在这里插入图片描述

表约束是需要在创建表的时候就给他设计的

非空约束 not null

  • 创建非空约束

crete table table_name (

id int not null,

sn int,

name varchar(20),

);

在这里插入图片描述

添加了⾮空约束之后,设置的字段就不能为空了。

  • 查看非空约束

在这里插入图片描述

  • 验证非空约束

在这里插入图片描述

唯一约束 unique

  • 创建唯一约束

create table student (

id int not null,

sn int unique,

name varchar(20),

);

在这里插入图片描述

  • 查看唯一约束

使⽤ show keys from table_name 可以查看索引详情

在这里插入图片描述

  • 验证唯一约束

在这里插入图片描述

问题: 给某个字段创建了唯一约束,没有指定非空约束

① 这个字段是否可以插入null值?

② 这个字段是否可以插入空值?

_可以插入null,也是可以重复插入null的。对于null来说,并不是一个“值”,它相当于“为空”,就是“没有”的意思。

可以插入空值,但是不可以重复插入空值,和__null_*在查询上的区别就是“空”是可以被查询出来的,用它作为条件去查询到结果,而null是“没有”的意思,是查询不到的。*

主键约束 primary key

主键是可以⽤来表示⼀张表中某条数据的代表凭证,例如对于“⼈”这张表来说,唯⼀的身份证就可以作 为主键来代表这个⼈,“姓名”不⾏,因为姓名有可能会重复。

主键的特征:

  1. 主键可以由多个字段或单个字段组成。

  2. 主键不能为空且且唯一。

  3. 一个表中只能有⼀个主键。

指定id列为主键:

  • 独立主键

create table table_name(

id int not null PRIMARY KEY,

sn int unique,

name varchar(20) default’unkown’,

qq_mail varchar(20)

);

在这里插入图片描述

  • 联合主键

create table table_name(

id int,

name varchar(250),

primary key(id,name)

);

在这里插入图片描述

注意事项,设置主键字段不能为 null,否则会报错。

面试题:主键约束 VS 唯⼀约束

① 一个表中主键约束只能有一个,而唯一约束可以有多个。

② 唯一约束可以插入一个或多个null,而主键约束不允许插入null。

外键约束 foreign key

foreign key (字段名) references 主表(列)

案例:

创建班级表classes,id为主键:

– 创建班级表,有使⽤MySQL关键字作为字段时,需要使⽤``来标识

create table classes (

id int primary key,

name varchar(250),

desc text

);

创建学⽣表student,⼀个学⽣对应⼀个班级,⼀个班级对应多个学⽣。使⽤id为主键,classes_id 为外键,关联班级表id

– 重新设置学⽣表结构

drop table if exists student;

create table student (

id int primary key auto_increment,

sn int unique,

name varchar(250) default’unkown’,

classes_id int,

foreign key(classes_id) references classes(id)

);

检查约束 check

检查约束是保证列中的值符合指定的条件,⽐如性别只能插⼊“男”或者“⼥”。

检查约束 check 使⽤语法:

check(<检查约束>)

create table test_user (

id int,

name varchar(20),

sex varchar(1),

check (sex =‘男’ or sex=‘⼥’)

);

自增 auto_increment

create table test_user(

id int primary key auto_increment,

username varchar(250)

);

在这里插入图片描述

  • 注意事项:

① ⼀个表中只能有⼀个⾃增列。

② 2.⾃增列的字段类型只能为整数类型(TINYINT、SMALLINT、INT、BIGINT 等)。

③ auto_increment 必须配合 key ⼀起使⽤,这个 key 可以是 primary key,foreign key,如果没有 key 就会报错

④ 唯⼀列可以为自增列

⑤ 外键也可以为自增列

  • 查看自增值

show create table table_name;

show create table table_name\G;

在这里插入图片描述

  • 手动设置自增值

在这里插入图片描述

  • 修改自增值

注意事项:auto_increment 的值只能设置⽐⽬前存储的最⼤值⼤,否则设置不会⽣效。

alter table table_name auto_increment=n;

  • delete 和 truncate 重置自增验证

delete 不重置⾃增:

truncate 重置⾃增:

在这里插入图片描述

在这里插入图片描述

默认约束 default

默认约束是给没有给列赋值时的默认值,⽤法如下:

create table test_user(

id int primary key auto_increment,

sex varchar(1) default ‘男’

);

在这里插入图片描述

insert…select

将一张表的某一字段的数据完全的插入令一张新表中,按照字段的顺序进行匹配。

在这里插入图片描述

在这里插入图片描述

4. 表的设计规则-数据库设计的三范式


第一范式(确保每列保持原子性)

第⼀范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原⼦值,就说明该数据库表满足了第⼀范式。 第⼀范式的合理遵循需要根据系统的实际需求来定。

错误示例:

在这里插入图片描述

“地址”这个属性,本来直接将“地 址”属性设计成⼀个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地 址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某⼀部分操作的时候将非常方便

正确示例:

在这里插入图片描述

上表所示的用户信息遵循了第⼀范式的要求,这样在对⽤户使⽤城市进⾏分类的时候就⾮常⽅便,也提高了数据库的性能。

第二范式(确保表中的每列都和主键相关)

第⼆范式在第⼀范式的基础之上更进⼀层。第⼆范式需要确保数据库表中的每⼀列都和主键相关,而不能只与主键的某 ⼀部分相关(主要针对联合主键⽽⾔)。也就是说在⼀个数据库表中,⼀个表中只能保存⼀种数据,不可以把多种数据 保存在同⼀张数据库表中。

不符合示例:

在这里插入图片描述

这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信 息不与该表的主键相关,⽽仅仅是与商品编号相关。所以在这⾥违反了第⼆范式的设计原则。

正确示例:

在这里插入图片描述

这样设计,在很⼤程度上减⼩了数据库的冗余。如果要获取订单的商品信息,使⽤商品编号到商品信息表中查询即可。

第三范式(确保每列都和主键列直接相关,而不是间接相关)

第三范式需要确保数据表中的每⼀列数据都和主键直接相关,而不能间接相关,并且每一个字段都不能和非主键字段有依赖。

比如在设计⼀个订单数据表的时候,可以将客户编号作为⼀个外键和订单表建⽴相应的关系。⽽不可以在订单表中添加 关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是⼀个满⾜第三范式的数据库表。 不符合第三范式:

在这里插入图片描述

正确表结构:

在这里插入图片描述

这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输⼊客户信息的内容,减小了数据冗余。

范式优点:实现列和非主键的解耦!

修改了一个字段,不会影响其他字段,优秀的设计理念。“高内聚 低耦合”

5. 表结构


表和表之间的关系有三种:

  • ⼀对⼀:⼀个学⽣对应⼀个学号。

  • ⼀对多:⼀个班级包含多个学⽣(⽤两张表表示)。

  • 多对多:⼀张表中的⼀条数据可以对应到另⼀张表的多条数据,反之也是这样的,这样的关系叫做多对多,⼀般⽤三个表表示。

在这里插入图片描述

高级SQL查询—3

============================================================================

1.聚合查询


常见的统计总数、计算平局值等操作,可以使⽤聚合函数来实现,常⻅的聚合函数有:

在这里插入图片描述

  • count 查询条数

– 统计班级共有多少同学

select count(*) from student;

select count(0) from student;

– 统计班级收集的 qq_mail 有多少个,qq_mail 为 NULL 的数据不会计⼊结果

select count(qq_mail) from student;

count用法1:

在这里插入图片描述

用法2

在这里插入图片描述

用法3

在这里插入图片描述

在不同的 count 统计场景下,要使用不同的 count 查询。

  • sum 函数

– 统计数学成绩总分

select sum(math) from exam_result;

– 不及格 < 60 的总分,没有结果,返回 NULL

select sum(math) from exam_result where math < 60;

在这里插入图片描述

  • avg函数

– 统计平均总分

select avg(chinese + math + english) 平均总分 from exam_result;

在这里插入图片描述

  • max / min 函数

– 返回英语最⾼分

select max(english) from exam_result;

– 返回 > 70 分以上的数学最低分

select min(math) from exam_result where math > 70;

  • ifnull 函数

ifnull 函数是 MySQL 控制流函数之一,它接受两个参数,如果不是 null,则返回第⼀个参数,否 则 ifnull 函数返回第⼆个参数。

select ifnull(expression_1,expression_2);

– 示例1

select ifnull(1,0); – returns 1

– 示例2

select ifnull(‘’,1); – returns ‘’

– 示例3

select ifnull(unll,‘Hello,Null’); – returns Hello,Null

解决总成绩为null的问题

在这里插入图片描述

使⽤ ifnull 函数来解决:

在这里插入图片描述

但是我们尽量是在开发中直接设置字段的约束为“not null”,尽量不调用数据库自己的函数。

  • 分组查询 group by

select 中使⽤ group by 子句可以对指定列进⾏分组查询。需要满足:使用 group by 进⾏分组查询时,select 指定的字段必须是“分组依据字段”,其他字段若想出现在 select 中则必须包含在聚合函数中。

select column1, sum(column2), … from table group by column1;

案例:

准备测试表及数据:职员表,有id(主键)、name(姓名)、role(⻆⾊)、salary(薪⽔)

– 查询每个⻆⾊的最⾼⼯资、最低⼯资和平均⼯资

select role,max(salary),min(salary),avg(salary) from emp group by role;

  • 分组条件查询 having

group by ⼦句进⾏分组以后,需要对分组结果再进⾏条件过滤时,不能使⽤ where 语句,而需要用 having

– 显示平均⼯资低于 1500 的⻆⾊和它的平均⼯资

select role,max(salary),min(salary),avg(salary) from emp group by role

having avg(salary)>1500;

最后

各位读者,由于本篇幅度过长,为了避免影响阅读体验,下面我就大概概括了整理了

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

select 中使⽤ group by 子句可以对指定列进⾏分组查询。需要满足:使用 group by 进⾏分组查询时,select 指定的字段必须是“分组依据字段”,其他字段若想出现在 select 中则必须包含在聚合函数中。

select column1, sum(column2), … from table group by column1;

案例:

准备测试表及数据:职员表,有id(主键)、name(姓名)、role(⻆⾊)、salary(薪⽔)

– 查询每个⻆⾊的最⾼⼯资、最低⼯资和平均⼯资

select role,max(salary),min(salary),avg(salary) from emp group by role;

  • 分组条件查询 having

group by ⼦句进⾏分组以后,需要对分组结果再进⾏条件过滤时,不能使⽤ where 语句,而需要用 having

– 显示平均⼯资低于 1500 的⻆⾊和它的平均⼯资

select role,max(salary),min(salary),avg(salary) from emp group by role

having avg(salary)>1500;

最后

各位读者,由于本篇幅度过长,为了避免影响阅读体验,下面我就大概概括了整理了

[外链图片转存中…(img-2onH8S8K-1713641418873)]

[外链图片转存中…(img-ECd7rC3q-1713641418874)]

[外链图片转存中…(img-2kaJQ6Er-1713641418875)]

[外链图片转存中…(img-GEtM8HjR-1713641418875)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-TgIA3Chk-1713641418876)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值