MySQL—— 基础语法大全及操作演示(下)—— 持续更新
- 三、函数
- 3.1 字符串函数
- 3.2 数值函数
- 3.3 日期函数
- 3.4 流程函数
- 四、约束
- 4.1 概述
- 4.2 约束演示
- 4.3 外键约束
- 4.3.1 介绍
- 4.3.2 语法
- 4.3.3 删除/更新行为
- 五、多表查询
- 5.1 多表关系
- 5.1.1 一对多
- 5.1.2 多对多
- 5.1.3 一对一
- 5.2 多表查询概述
- 5.2.1 数据准备
- 5.2.2 概述
- 5.2.3 分类
- 5.3 内连接
- 5.4 外连接
- 5.5 自连接
- 5.5.1 自连接查询
- 5.5.2 联合查询
- 5.6 子查询
- 5.6.1 概述
- 5.6.2 标量子查询
- 5.6.3 列子查询
- 5.6.4 行子查询
- 5.6.5 表子查询
- 六、事务
- 6.1 事务简介
- 6.2 事务操作
- 6.2.1 未控制事务
- 6.2.2 控制事务一
- 6.2.3 控制事务二
- 6.3 事务四大特性
- 6.4 并发事务问题
- 6.5 事务隔离级别
MySQL— 基础语法大全及操作演示!!!(上)https://blog.csdn.net/weixin_43412762/article/details/132051493
三、函数
函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着,这一段程序或代码在MySQL中
已经给我们提供了,我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即可。
那么,函数到底在哪儿使用呢?
我们先来看两个场景:
- 在企业的OA或其他的人力系统中,经常会提供的有这样一个功能,每一个员工登录上来之后都能够看到当前员工入职的天数。 而在数据库中,存储的都是入职日期,如 2017-11-12,那如果快速计算出天数呢?
- 在做报表这类的业务需求中,我们要展示出学员的分数等级分布。而在数据库中,存储的是学生的分数值,如98/75,如何快速判定分数的等级呢?
其实,上述的这一类的需求呢,我们通过MySQL中的函数都可以很方便的实现 。
MySQL中的函数主要分为以下四类: 字符串函数、数值函数、日期函数、流程函数。
3.1 字符串函数
MySQL中内置了很多字符串函数,常用的几个如下:
举个栗子: 由于业务需求变更,企业员工的工号,统一为5位数,目前不足5位数的全部在前面补0。比如: 1号员工的工号应该为00001。
update emp set workno = lpad(workno, 5, '0');
3.2 数值函数
常见的数值函数如下:
举个栗子: 通过数据库的函数,生成一个六位数的随机验证码。
- 思路: 获取随机数可以通过rand()函数,但是获取出来的随机数是在0-1之间的,所以可以在其基础
上乘以1000000,然后舍弃小数部分,如果长度不足6位,补0
select lpad(round(rand()*1000000 , 0), 6, '0');
3.3 日期函数
常见的日期函数如下:
举个栗子: 查询所有员工的入职天数,并根据入职天数倒序排序。
- 思路: 入职天数,就是通过当前日期 - 入职日期,所以需要使用
datediff
函数来完成。
select name, datediff(curdate(), entrydate) as 'entrydays' from emp order by entrydays desc;
3.4 流程函数
流程函数也是很常用的一类函数,可以在SQL语句中实现 条件筛选,从而提高语句的效率。
举个栗子: 需求: 查询emp表的员工姓名和工作地址 (北京/上海 ----> 一线城市 , 其他 ----> 二线城市)
selectname,( case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else'二线城市' end ) as '工作地址'
from emp;
🚀🚀🚀 函数操作 快速食用:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
## 3.1 字符串函数-----------------------------------------------------
# 1. concat : 字符串拼接
select concat('1 Hello', ' MySQL');
# 2. lower : 全部转小写
select lower('Hello');
# 3. upper : 全部转大写
select upper('Hello');
# 4. lpad : 左填充,达到5个字符
select lpad('01', 5, '-');
# 5. rpad : 右填充,达到5个字符
select rpad('01', 5, '-');
# 6. trim : 去除头尾空格
select trim(' Hello MySQL ');
# 7. substring : 截取子字符串,从第一个截取5个字符
select substring('r Hello MySQL', 1, 5);## 3.2 数值函数-------------------------------------------------------
# 1. ceil:向上取整,值为2
select ceil(1.1);
# 2. floor:向下取整,值为1
select floor(1.9);
# 3. mod:取模,值为3
select mod(7, 4);
# 4. rand:获取随机数
select rand();
# round:四舍五入,值为2.34
select round(2.344, 2);## 3.3 日期函数-------------------------------------------------------
# 1. curdate:当前日期
select curdate();
# 2. curtime:当前时间
select curtime();
# 3. now:当前日期和时间
select now();
# 4. YEAR , MONTH , DAY:当前年、月、日
select year(now());
select month(now());
select day(now());
# 5. date_add:增加指定的时间间隔
select date_add(now(), interval 70 year );
# 6. datediff:获取两个日期相差的天数
select datediff('2021-10-01', '2021-12-01');## 3.4 流程函数-------------------------------------------------------
# 1. if,返回 Error
select if(false, 'Ok', 'Error');
# 2. ifnull
select ifnull('Ok','Default'); # 返回 Ok
select ifnull('','Default'); # 返回 ‘’
select ifnull(null,'Default'); # 返回 Default
# 3. case when then else end
selectname,( case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else'二线城市' end ) as '工作地址'
from emp;
四、约束
4.1 概述
- 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
- 目的:保证数据库中数据的正确、有效性和完整性。
- 分类:
primary key
:存在且唯一;unique
:只需唯一,不一定存在。
注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
4.2 约束演示
上面我们介绍了数据库中常见的约束,以及约束涉及到的关键字,那这些约束我们到底如何在创建表、修改表的时候来指定呢,接下来我们就通过一个案例,来演示一下。
案例需求: 根据需求,完成表结构的创建。需求如下:
对应的建表语句为:
create table tb_user(id int auto_increment primary key comment 'ID唯一标识',name varchar(10) not null unique comment '姓名' ,age int check (age > 0 && age <= 120) comment '年龄' ,status char(1) default '1' comment '状态',gender char(1) comment '性别'
) comment '用户表';
4.3 外键约束
4.3.1 介绍
外键:用来让两张表的数据之间建立连接,从而保证数据的 一致性 和 完整性。
4.3.2 语法
1). 添加外键
create table 表名(字段名 数据类型,...[constraint] [外键名称] foreign key (外键字段名) references 主表 (主表列名)
);
alter table 表名 add constraint 外键名称 foreign key (外键字段名) references 主表 (主表列名) ;
4.3.3 删除/更新行为
添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种:
具体语法为:
alter table 表名 add constraint 外键名称 foreign key(外键字段) references 主表名 (主表字段名) on update cascade on delete cascade;
演示如下:
由于 no action
是默认行为,我们前面语法演示的时候,已经测试过了,就不再演示了,这里我们再
演示其他的两种行为:cascade
、set null
。
⭐️ 1). CASCADE
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update cascade on delete cascade ;
⭐️ 2). SET NULL
在进行测试之前,我们先需要删除上面建立的外键 fk_emp_dept_id
。然后再通过数据脚本,将 emp
、dept
表的数据恢复了。
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update set null on delete set null ;
五、多表查询
在讲解 SQL语句 的时候,讲解了DQL语句,也就是数据查询语句,但是之前讲解的查询都是单表查询,而本章节我们要学习的则是多表查询操作,主要从以下几个方面进行讲解。
5.1 多表关系
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结
构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:
- 一对多(多对一)
- 多对多
- 一对一
5.1.1 一对多
5.1.2 多对多
5.1.3 一对一
5.2 多表查询概述
5.2.1 数据准备
5.2.2 概述
多表查询就是指从多张表中查询数据。
- 原来查询单表数据,执行的SQL形式为:
select * from emp
; - 那么我们要执行多表查询,就只需要使用逗号分隔多张表即可,如:
select * from emp, dept
;
具体的执行结果如下:
5.2.3 分类
- 连接查询
- 内连接:相当于查询
A
、B
交集部分数据 - 外连接:
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据 - 自连接:当前表与自身的连接查询,自连接必须使用表别名
- 内连接:相当于查询
- 子查询
5.3 内连接
内连接查询的是两张表交集部分的数据。(也就是绿色部分的数据).
内连接的语法分为两种: 隐式内连接、显式内连接。先来学习一下具体的语法结构。
1). 隐式内连接
select 字段列表 from 表1 , 表2 where 条件 ... ;
2). 显式内连接
select 字段列表 from 表1 [ inner ] join 表2 on 连接条件 ... ;
表的别名:
- ①.
tablea as 别名1 , tableb as 别名2 ;
- ②.
tablea 别名1 , tableb 别名2 ;
注意事项:
一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字段。
5.4 外连接
外连接分为两种,分别是:左外连接 和 右外连接。具体的语法结构为:
⭐️ 1). 左外连接
select 字段列表 from 表1 left [ outer ] join 表2 on 条件 ... ;
- 左外连接相当于查询 表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。
⭐️ 2). 右外连接
select 字段列表 from 表1 right [ outer ] join 表2 on 条件 ... ;
- 右外连接相当于查询 表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。
5.5 自连接
5.5.1 自连接查询
自连接查询,顾名思义,就是自己连接自己,也就是把一张表连接查询多次。我们先来学习一下自连接的查询语法:
select 字段列表 from 表A 别名A join 表A 别名B on 条件 ... ;
- 而对于自连接查询,可以是内连接查询,也可以是外连接查询。
注意事项:
- 在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。
5.5.2 联合查询
对于 union
查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
select 字段列表 from 表A ...
union [ all ]
select 字段列表 from 表B ....;
- 对于联合查询的多张表的 列数 必须保持一致,字段类型 也需要保持一致。
union all
会将全部的数据直接合并在一起,union
会对合并之后的数据去重。
注意:
- 如果多条查询语句查询出来的结果,字段数量 不一致,在进行
union/union all
联合查询时,将会报错。
5.6 子查询
5.6.1 概述
⭐️ 1). 概念
SQL语句中嵌套 SELECT
语句,称为嵌套查询,又称子查询。
select * from t1 where column1 = ( select column1 from t2 );
- 子查询外部的语句可以是
insert / update / delete / select
的任何一个。
⭐️ 2). 分类
根据子查询结果不同,分为:
- A. 标量子查询(子查询结果为单个值)
- B. 列子查询 (子查询结果为一列)
- C. 行子查询 (子查询结果为一行)
- D. 表子查询 (子查询结果为多行多列)
根据子查询位置,分为:
- A.
where
之后 - B.
from
之后 - C.
select
之后
5.6.2 标量子查询
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
- 常用的操作符:
=
<>
>
>=
<
<=
5.6.3 列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
- 常用的操作符:
in
、not in
、any
、some
、all
5.6.4 行子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
- 常用的操作符:
=
、<>
、in
、not in
5.6.5 表子查询
子查询返回的结果是 多行多列,这种子查询称为表子查询。
- 常用的操作符:
in
六、事务
6.1 事务简介
事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
就比如: 张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加1000。 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。
- 正常情况: 转账这个操作, 需要分为以下这么三步来完成 , 三步完成之后, 张三减少1000, 而李四增加1000, 转账成功。
- 异常情况: 转账这个操作, 也是分为以下这么三步来完成 , 在执行第三步是报错了, 这样就导致张三减少1000块钱, 而李四的金额没变, 这样就造成了数据的不一致, 就出现问题了。
- 为了解决上述的问题,就需要通过数据的事务来完成,我们只需要在业务逻辑执行之前开启事务,执行完毕后提交事务。如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态。
注意: 默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务。
6.2 事务操作
6.2.1 未控制事务
6.2.2 控制事务一
⭐️ 1). 查看/设置事务提交方式
select @@autocommit ;
set @@autocommit = 0 ;
⭐️ 2). 提交事务
commit;
⭐️ 3). 回滚事务
rollback;
注意:上述的这种方式,我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提交, 此时我们执行的DML语句都不会提交, 需要手动的执行
commit
进行提交。
6.2.3 控制事务二
⭐️ 1). 开启事务
start transaction 或 begin ;
⭐️ 2). 提交事务
commit;
⭐️ 3). 回滚事务
rollback;
6.3 事务四大特性
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
上述就是事务的四大特性,简称 ACID。
6.4 并发事务问题
⭐️ 1). 赃读:一个事务读到另外一个事务还没有提交的数据。
- 比如B读取到了A未提交的数据。
⭐️ 2). 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
- 事务A两次读取同一条记录,但是读取到的数据却是不一样的。
⭐️ 3). 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了 “幻影”。
6.5 事务隔离级别
为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下几种:
⭐️ 1). 查看事务隔离级别
select @@transaction_isolation;
⭐️ 2). 设置事务隔离级别
set [ session | global ] transaction isolation level { read uncommitted | read committed | repeatable read | serializable }
注意:事务隔离级别越高,数据越安全,但是性能越低。