文章目录
-
- 一、MySQL基础
-
- [1. MySQL安装](#1. MySQL安装)
- [2. SQL](#2. SQL)
-
- [2.1.1 SQL分类:DDL、DML、DQL、DCL](#2.1.1 SQL分类:DDL、DML、DQL、DCL)
- [2.2.1 DDL :定义数据库对象(数据库,表,字段)](#2.2.1 DDL :定义数据库对象(数据库,表,字段))
-
- [2.2.1.1 查询数据库、创建数据库、删除数据库、使用数据库](#2.2.1.1 查询数据库、创建数据库、删除数据库、使用数据库)
- [2.2.1.2 表操作:创建表、查询所有表、查询表结构、查询指定表的建表语句](#2.2.1.2 表操作:创建表、查询所有表、查询表结构、查询指定表的建表语句)
-
- [1. 创建表](#1. 创建表)
- [2. 查询当前数据库所有表](#2. 查询当前数据库所有表)
- [3. 查询表结构](#3. 查询表结构)
- [4. 查询指定表的建表语句](#4. 查询指定表的建表语句)
- [2.2.1.3 表操作-修改表:添加字段、修改字段名/修改字段类型、删除字段、修改表名](#2.2.1.3 表操作-修改表:添加字段、修改字段名/修改字段类型、删除字段、修改表名)
-
- [1. 添加字段](#1. 添加字段)
- [2. 修改字段:修改字段类型、修改字段名和字段类型](#2. 修改字段:修改字段类型、修改字段名和字段类型)
- [3. 删除字段](#3. 删除字段)
- [4. 修改表名](#4. 修改表名)
- [2.2.1.4 表操作-删除表](#2.2.1.4 表操作-删除表)
- [2.2.1.5 表操作-MySQL支持的数据类型](#2.2.1.5 表操作-MySQL支持的数据类型)
-
- [1. 数值类型](#1. 数值类型)
- [2. 字符串类型](#2. 字符串类型)
- [3. 日期时间类型](#3. 日期时间类型)
- [2.2.2 DML :对数据库表中的数据进行增、删、改](#2.2.2 DML :对数据库表中的数据进行增、删、改)
-
- [2.2.2.1 添加数据 insert into 表名 values](#2.2.2.1 添加数据 insert into 表名 values)
-
- [1. 给指定字段添加数据](#1. 给指定字段添加数据)
- [2. 给全部字段添加数据](#2. 给全部字段添加数据)
- [3. 批量添加数据:values 后每条记录逗号隔开](#3. 批量添加数据:values 后每条记录逗号隔开)
- [2.2.2.2 修改数据 update 表名 set 字段 where 条件](#2.2.2.2 修改数据 update 表名 set 字段 [where 条件])
-
- [1. 修改数据](#1. 修改数据)
- [2.2.2.3 删除数据 delete form 表名 where 条件](#2.2.2.3 删除数据 delete form 表名 [where 条件])
-
- [1. 删除数据](#1. 删除数据)
- [2.2.3 DQL :对数据库表中的数据进行查询](#2.2.3 DQL :对数据库表中的数据进行查询)
-
- [2.2.3.0 查询语句的基本语法结构](#2.2.3.0 查询语句的基本语法结构)
- [2.2.3.1 基本查询](#2.2.3.1 基本查询)
-
- [1. 多字段查询](#1. 多字段查询)
- [2. 设置别名 as](#2. 设置别名 as)
- [3. 去除重复记录 distinct](#3. 去除重复记录 distinct)
- [2.2.3.2 条件查询(where)、比较运算符、逻辑运算符](#2.2.3.2 条件查询(where)、比较运算符、逻辑运算符)
- [2.2.3.3 聚合函数(count、max、min、avg、sum)](#2.2.3.3 聚合函数(count、max、min、avg、sum))
- [2.2.3.4 分组查询(group by):一般和聚合函数一起使用](#2.2.3.4 分组查询(group by):一般和聚合函数一起使用)
- [2.2.3.5 排序查询(order by): asc(默认值,可省略)、desc](#2.2.3.5 排序查询(order by): asc(默认值,可省略)、desc)
- [2.2.3.6 分页查询(limit)](#2.2.3.6 分页查询(limit))
- [2.2.3.7 DQL语句的执行顺序](#2.2.3.7 DQL语句的执行顺序)
- [2.2.4 DCL :管理数据库用户、控制访问权限](#2.2.4 DCL :管理数据库用户、控制访问权限)
-
- [2.2.4.0 管理用户](#2.2.4.0 管理用户)
-
- [1. 查询用户](#1. 查询用户)
- [2. 创建用户](#2. 创建用户)
- [3. 修改用户密码](#3. 修改用户密码)
- [4. 删除用户](#4. 删除用户)
- [2.2.4.1 权限控制](#2.2.4.1 权限控制)
-
- [1. 查询权限](#1. 查询权限)
- [2. 授予权限](#2. 授予权限)
- [3. 撤销权限](#3. 撤销权限)
- [3. 函数](#3. 函数)
-
- [3.1.1 字符串函数](#3.1.1 字符串函数)
- [3.2.1 数值函数](#3.2.1 数值函数)
- [3.3.1 日期函数](#3.3.1 日期函数)
- [3.4.1 流程控制函数](#3.4.1 流程控制函数)
- [4. 约束](#4. 约束)
-
- [4.1.1 各类型约束示例](#4.1.1 各类型约束示例)
- [4.1.2 外键约束的示例(子表、父表)](#4.1.2 外键约束的示例(子表、父表))
-
- [4.1.2.1 添加外键约束、删除外键约束](#4.1.2.1 添加外键约束、删除外键约束)
-
- [1. 创建表时,添加外键约束](#1. 创建表时,添加外键约束)
- [2. 修改表时,添加外键约束](#2. 修改表时,添加外键约束)
- [3. 删除外键约束](#3. 删除外键约束)
- [4.1.2.2 在外键约束下,删除/更新行为](#4.1.2.2 在外键约束下,删除/更新行为)
- [5. 多表查询](#5. 多表查询)
-
- [5.1.1 多表关系、多表查询概述](#5.1.1 多表关系、多表查询概述)
-
- [5.1.1.1 多表关系](#5.1.1.1 多表关系)
- [5.1.1.2 多表查询的概述、笛卡尔积(在多表查询时,需要消除无效的笛卡尔积)](#5.1.1.2 多表查询的概述、笛卡尔积(在多表查询时,需要消除无效的笛卡尔积))
- [5.1.2 连接查询:内连接、外连接、自连接](#5.1.2 连接查询:内连接、外连接、自连接)
-
- [5.1.2.1 内连接(隐式内连接、显示内连接): 相当于查询A、B交集部分数据](#5.1.2.1 内连接(隐式内连接、显示内连接): 相当于查询A、B交集部分数据)
-
- [1. 隐式内连接](#1. 隐式内连接)
- [2. 显式内连接 : inner 可以省略](#2. 显式内连接 : inner 可以省略)
- 3.内连接的示例演示(隐式内连接/显式内连接)
- [5.1.2.2 外连接:(左外连接、右外连接)'outer'可以省略](#5.1.2.2 外连接:(左外连接、右外连接)'outer'可以省略)
-
- [1. 左外连接:查询左表所有数据,以及两张表交集部分数据](#1. 左外连接:查询左表所有数据,以及两张表交集部分数据)
- [2. 右外连接:查询右表所有数据,以及两张表交集部分数据](#2. 右外连接:查询右表所有数据,以及两张表交集部分数据)
- [3. 外连接的示例演示(左外连接、右外连接)'outer'可以省略](#3. 外连接的示例演示(左外连接、右外连接)'outer'可以省略)
- [5.1.2.3 自连接:可以是内连接查询、也可是外连接查询](#5.1.2.3 自连接:可以是内连接查询、也可是外连接查询)
-
- [1. 内连接的示例演示](#1. 内连接的示例演示)
- [5.1.3 联合查询、子查询](#5.1.3 联合查询、子查询)
-
- [5.1.3.1 联合查询(union,union all):把多次查询的结果合并,形成一个新的查询结果集;](#5.1.3.1 联合查询(union,union all):把多次查询的结果合并,形成一个新的查询结果集;)
- [5.1.3.2 子查询:SQL语句中嵌套select语句,称为嵌套查询,又称子查询;](#5.1.3.2 子查询:SQL语句中嵌套select语句,称为嵌套查询,又称子查询;)
-
- [1. 子查询语法](#1. 子查询语法)
- [2. 根据子查询结果不同,分为如下:](#2. 根据子查询结果不同,分为如下:)
- [3. 根据子查询位置,分为:where之后、from之后、select之后;(示例在上一点);](#3. 根据子查询位置,分为:where之后、from之后、select之后;(示例在上一点);)
- [5.1.4 多表查询示例](#5.1.4 多表查询示例)
- [6. 事务:四大特性、分类、其提交方式修改、开启事务、提交事务、回滚事务](#6. 事务:四大特性、分类、其提交方式修改、开启事务、提交事务、回滚事务)
-
- [6.1.1 查询并修改事务的提交方式(自动提交、手动提交)(Mysql默认自动、Oracle默认手动)](#6.1.1 查询并修改事务的提交方式(自动提交、手动提交)(Mysql默认自动、Oracle默认手动))
-
- [6.1.1.1 查询并设置事务的提交方式](#6.1.1.1 查询并设置事务的提交方式)
- [6.1.1.2 提交事务、回滚事务](#6.1.1.2 提交事务、回滚事务)
- [6.1.1.3 手动提交事务的效果-示例:](#6.1.1.3 手动提交事务的效果-示例:)
- [6.1.2 并发事务问题](#6.1.2 并发事务问题)
- [6.1.3 事务的隔离级别,及不同隔离级别解决了并发事务的问题(√表示会发生、×表示不会发生)](#6.1.3 事务的隔离级别,及不同隔离级别解决了并发事务的问题(√表示会发生、×表示不会发生))
-
- [6.1.3.1 事务的隔离级别的查看、设置](#6.1.3.1 事务的隔离级别的查看、设置)
一、MySQL基础
1. MySQL安装
2. SQL
2.1.1 SQL分类:DDL、DML、DQL、DCL
| 分类 | 全称 | 说明 |
|---|---|---|
| DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库,表,字段) |
| DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
| DQL | Data Query Language | 数据查询语言,用来查询数据库中表的记录 |
| DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
2.2.1 DDL :定义数据库对象(数据库,表,字段)
2.2.1.1 查询数据库、创建数据库、删除数据库、使用数据库
1.查询所有数据库
sql
SHOW DATABASES;
2.查询当前数据库
sql
select DATABASE();
3.创建数据库
sql
create database [if not exists] 数据库名[default charset 字符集][collate 排序规则];
-- 如果名称不存在则创建,否则不执行;
-- 字符集:utf8、utf8mb4
4.删除数据库
sql
drop database [if exists]数据库名;
-- 存在则删除,否则不执行;
5.使用数据库
sql
use 数据库名;
2.2.1.2 表操作:创建表、查询所有表、查询表结构、查询指定表的建表语句
1. 创建表
sql
create table 表名(
字段1 字段1类型[comment 字段1注释],
......
)[comment 表注释];
-- 举例:
CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL comment '员工姓名',
`gender` tinyint(1) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`department` varchar(255) DEFAULT NULL,
`salary` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 comment '员工表';
2. 查询当前数据库所有表
sql
show tables;
3. 查询表结构
sql
desc 表名;
4. 查询指定表的建表语句
sql
show create table 表名;
2.2.1.3 表操作-修改表:添加字段、修改字段名/修改字段类型、删除字段、修改表名
1. 添加字段
sql
alter table 表名 add 字段名 类型(长度) [comment 注释][约束];
# 添加字段-举例:多个字段 逗号隔开;
alter table employee add a int(100),add b VARCHAR(200);
2. 修改字段:修改字段类型、修改字段名和字段类型
sql
修改字段类型
alter table 表名 modify 字段名 新数据类型(长度);
修改字段名和字段类型
alter table 表名 change 旧字段名 新字段名 类型(长度) [comment 注释][约束];
3. 删除字段
sql
修改字段类型
alter table 表名 drop 字段名;
# 删除字段-举例:多个字段 逗号隔开;
alter table employee drop a, drop b;
4. 修改表名
sql
alter table 表名 rename to 新表名;
2.2.1.4 表操作-删除表
sql
删除表:
drop table [if exists]表名;
删除指定表,并重新创建该表:
truncate table 表名;
2.2.1.5 表操作-MySQL支持的数据类型
1. 数值类型

2. 字符串类型

3. 日期时间类型

2.2.2 DML :对数据库表中的数据进行增、删、改
2.2.2.1 添加数据 insert into 表名 values
1. 给指定字段添加数据
sql
insert into 表名(字段1,字段2,......)values(值1,值2,......);
2. 给全部字段添加数据
sql
insert into 表名 values(值1,值2,......);
3. 批量添加数据:values 后每条记录逗号隔开
sql
insert into 表名(字段1,字段2,......)values(值1,值2,......),(值1,值2,......),(值1,值2,......);
insert into 表名 values(值1,值2,......),(值1,值2,......),(值1,值2,......);
2.2.2.2 修改数据 update 表名 set 字段 where 条件
1. 修改数据
sql
update 表名 set 字段1=值1,字段2=值2,......where 条件;
举例:
update employee set name ='李倩梅' where name = '红蝶';
2.2.2.3 删除数据 delete form 表名 where 条件
1. 删除数据
sql
delete from 表名 [where 条件];
2.2.3 DQL :对数据库表中的数据进行查询
2.2.3.0 查询语句的基本语法结构
sql
select
字段列表
from
表名列表
where
条件列表
group by
分组字段列表
having
分组后条件列表
order by
排序字段列表
limit
分页参数
2.2.3.1 基本查询
1. 多字段查询
sql
查询多个字段
select 字段1,字段2,......from 表名;
查询所有字段
select * from 表名;
2. 设置别名 as
sql
select 字段1 [as 别名1],字段2 [as 别名2],......from 表名;
--设置别名非必须;且 设置别名时,as也是可以省略;
3. 去除重复记录 distinct
sql
select distinct 字段列表 from 表名;
2.2.3.2 条件查询(where)、比较运算符、逻辑运算符
sql
select
字段列表
from
表名列表
where
条件列表
| 比较运算符 | 功能 |
|---|---|
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| = | 等于 |
| <>或!= | 不等于 |
| between......and...... | 在某个范围之内(含最小、最大值) |
| in(......) | 在in之后的列表中的值,多选一 |
| like 占位符 | 模糊匹配(_匹配单个字符,%匹配任意个字符) |
| is null | 是null |
| 比较运算符 | 功能 |
|---|---|
| and 或 && | 并且(多个条件同时成立) |
| or | 或者(多个条件任意一个成立) |
| not 或 ! | 非,不是 |
2.2.3.3 聚合函数(count、max、min、avg、sum)
所有的null值不参与聚合函数的运算;

sql
select count(*) from emp; # 统计数量
select avg(age) from emp;#平均年龄
select max(age) from emp; #最大年龄
select min(age) from emp; #最小年龄
select sum(age) from emp;#年龄求和
2.2.3.4 分组查询(group by):一般和聚合函数一起使用
sql
select 字段列表 from 表名列表
[where 条件列表]
group by 分组字段
[having 分组后过滤条件]
举例:
SELECT gender,COUNT(*) FROM emp GROUP BY gender; #以性别分组,统计不同性别的员工数量;
SELECT gender,avg(age) from emp GROUP BY gender; #以性别分组,计算不同性别的员工平均年龄;
# 查询年龄小于45的员工,根据工作地址分组,获取员工数量大于等于3的工作地址;
SELECT workaddress,count(*) as address_count FROM emp
WHERE age < 45
GROUP BY workaddress HAVING address_count>=3;
2.2.3.5 排序查询(order by): asc(默认值,可省略)、desc
sql
select 字段列表 from 表名
where 条件列表
order by 字段1 asc,字段2,desc,......;
2.2.3.6 分页查询(limit)
sql
select 字段列表 from 表名
limit 起始索引,查询记录数;
# 起始索引从0开始;
# 查询第一页,可以省略0;
举例:查询第1页员工数据,每页展示10条记录
select * from emp limit 0, 10; # select * from emp limit 10; 省略0也可;
2.2.3.7 DQL语句的执行顺序

2.2.4 DCL :管理数据库用户、控制访问权限
2.2.4.0 管理用户
1. 查询用户
sql
use mysql;
select * from user;
2. 创建用户
sql
create user '用户名'@'主机名' identified by '密码';
#举例:创建用户zhangsan,可以在当前主机localhost访问数据库,密码123456
create user 'zhangsan'@'localhost' identified by '123456';
#举例:创建用户zhangsan,可以在任意主机访问数据库,密码123456
create user 'zhangsan'@'%' identified by '123456';
3. 修改用户密码
sql
alter user '用户名'@'主机名' identified with by mysql_native_password '新密码';
4. 删除用户
sql
drop user '用户名'@'主机名' ;
2.2.4.1 权限控制

1. 查询权限
sql
show grants for '用户名'@'主机名';
2. 授予权限
sql
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
3. 撤销权限
sql
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
3. 函数
3.1.1 字符串函数
MySQL中内置了很多字符串函数,常用的几个如下:
| 函数 | 功能 |
|---|---|
| concat(S1,S2,...Sn) | 字符串拼接,将s1,s2......Sn拼接成一个字符串 |
| lower(str) | 将字符串str全部转为小写 |
| upper(str) | 将字符串str全部转为大写 |
| lpad(str,n,pad) | 左填充,用字符串pad对str的左边进行填充 ,达到n个字符串长度 |
| rpad(str,n,pad) | 右填充,用字符串pad对str的右边进行填充 ,达到n个字符串长度 |
| trim(str) | 去掉字符串头部和尾部的空格 |
| substring(str,start,len) | 返回从字符串str从start位置起的len个长度的字符串 |
sql
select concat('hello','mysql');#--返回:hellomysql
select lower("Hello");#--返回:hello
select upper("Hello");#--返回:HELLO
select lpad('01',5,'-');#--返回:---01
select rpad('01',5,'-');#--返回:01---
select trim(' hello mysql ');#--返回:hello mysql
select substring('Hello MySql',1,5);#--返回:Hello
举例:修改emp中workno-不足5位,前面补0,使其长度为5位字符串
update emp set workno = lpad(workno,5,'0');
3.2.1 数值函数
| 函数 | 功能 |
|---|---|
| ceil(x) | 向上取整 |
| floor(x) | 向下取整 |
| mod(x,y) | 返回x/y的模 |
| rand() | 返回0~1内的随机数 |
| round(x,y) | 求参数x的四舍五入的值,保留y位小数 |
sql
select ceil(2.1);#--返回:3
select floor(2.9);#--返回:2
select mod(7,4);#--返回:3
select rand();#--返回:0~1之间随机数
select round(5.465,2);#--返回:5.47
举例:通过数据库的函数,生成一个六位数的随机验证码
select lpad(round(rand()*1000000,0),6,'0');
3.3.1 日期函数
| 函数 | 功能 |
|---|---|
| curdate() | 返回当前日期 |
| curtime() | 返回当前时间 |
| now() | 返回当前日期和时间 |
| year(date) | 获取指定date的年份 |
| month(date) | 获取指定date的月份 |
| day(date) | 获取指定date的日期 |
| date_add(date,interval expr type) | 返回一个日期/时间值加上一个时间间隔expr后的时间值 |
| datediff(date1,date2) | 返回起始时间date1和结束时间date2直接的天数 |
sql
select CURDATE();#--返回:2026-02-30
select curtime();#--返回:24:00:00
select now();#--返回:2026-02-30 10:15:61
select year(now());#--返回:1000
select month(now());#--返回:12
select day(now());#--返回:31
select date_add('2026-01-01',interval 31 day);#--返回:2026-02-01
select date_add('2026-01-01',interval 31 month);#--返回:2028-08-01
select date_add(now(),interval 1 year);#--返回:2027-07-26 10:27:00
select datediff('2026-10-01','2025-10-01');#--返回:365
select datediff('2025-10-01','2026-10-01');#--返回:-365
举例:查询所有员工的入职天数,并且根据入职天数倒序排序
select name , datediff(curdate(),entrydate) as entryDays from emp ORDER BY entryDays desc;
3.4.1 流程控制函数
| 函数 | 功能 |
|---|---|
| if(value,t,f) | 如果value为true,则返回t,否则返回f |
| ifnull(value1,value2) | 如果value1不为空,返回value1,否则返回value2 |
| case when val1 then res1...else default end | 如果val1为true,返回res1,...否则返回默认值default |
| case expr when val1 then res1...else default end | 如果expr的值等于val1,返回res1,...否则返回默认值default |
sql
select if (true,'ok','error');#--返回:ok
select ifnull ('ok','default');#--返回:ok
select ifnull (null,'default');#--返回:default
举例:查询emp表中员工姓名和工作地址(北京/上海---一线城市;其他----》二线城市)
SELECT name,workaddress,
(case workaddress
when '上海' then '一线城市'
when '北京'then '一线城市'
else '二线城市' end )as '城市级别'
FROM emp;
举例:查询score表中同学的数学、英语、语文成绩,85以上展示优秀,60以上展示及格,否则不及格
select id,name,
(
case
when math >=85 then '优秀'
when math>=60 then '及格'
else '不及格'
end
) '数学',
(
case
when english >=85 then '优秀'
when english>=60 then '及格'
else '不及格'
end
) '英语',
(
case
when chinese >=85 then '优秀'
when chinese>=60 then '及格'
else '不及格'
end
) '语文'
from score;
4. 约束
约束是作用于表中字段上的规则,用于限制存储在表中的数据;保证数据库的数据的正确性、有效性、完整性。
| 约束 | 描述 | 关键字 |
|---|---|---|
| 非空约束 | 限制该字段的数据不能为null | not null |
| 唯一约束 | 保证该字段的所有值都是唯一、不重复的 | unique |
| 主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | primary key |
| 默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | default |
| 检查约束(8.0.16版本后) | 保证字段值满足某一个条件 | check |
| 外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | foreign key |
4.1.1 各类型约束示例
sql
create table user(
id int auto_increment primary key comment '主键', # 主键、自动增长auto_increment
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.1.2 外键约束的示例(子表、父表)
外键 :用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性;
子表 :存在外键的表
父表 :外键关联的表
4.1.2.1 添加外键约束、删除外键约束
1. 创建表时,添加外键约束
sql
create table 表名(
...包含外键字段...
constraint '外键名称' foreign key (外键字段名) references 主表(主表列名)
);
2. 修改表时,添加外键约束
sql
alter table 表名 add constraint '外键名称' foreign key (外键字段名) references 主表(主表列名);
3. 删除外键约束
sql
alter table 表名 drop foreign key 外键名称;
4.1.2.2 在外键约束下,删除/更新行为

sql
# on update cascade on delete cascade : 在更新时按照cascade行为操作、在删除时按照cascade行为操作
alter table 表名 add constraint 外键名称 foreign key (外键字段名) references 主表(主表列名) on update cascade on delete cascade;
5. 多表查询
5.1.1 多表关系、多表查询概述
5.1.1.1 多表关系
表与表之间的关系分为三种 :一对多、多对多、一对一
实现表与表的关系 :
一对一 :外键(在任意的一表添加外键,关联另一张表的主键,并且设置外键为唯一约束 unique)
一对多 :外键(在多的表添加外键,关联一的表的主键)
多对多:外键+中间表(中间表至少包含两个外键,分别关联两方主键)举例:学生表 与 课程表 就是多对多;
sql
create table student(
id int auto_increment primary key COMMENT 'ID主键',
name varchar(50) comment '姓名',
no varchar(50) comment '学号'
) COMMENT '学生表';
#insert into student values (null,'黛姬丝','2000100101'),(null,'王林','2000100102'),(null,'李慕婉','2000100103'),(null,'红蝶','2000100104'),(null,'十三','2000100105');
create table course(
id int auto_increment PRIMARY KEY COMMENT '主键',
name VARCHAR(50) COMMENT'课程名称'
) COMMENT'课程表';
#insert into course VALUES(null,'java'),(null,'php'),(null,'mysql'),(null,'python'),(null,'AI');
create table student_course(
id int auto_increment comment '主键' primary key,
studentid int not null comment'学生ID',
courseid int not null comment '课程ID',
constraint fk_courseid foreign key (courseid) references course(id),
constraint fk_studentid foreign key (studentid) references student(id)
) COMMENT '中间表';
#insert into student_course VALUES (null,1,1), (null,1,2), (null,1,3), (null,2,2), (null,2,3), (null,3,4);
5.1.1.2 多表查询的概述、笛卡尔积(在多表查询时,需要消除无效的笛卡尔积)
笛卡尔积:两张表A集合与B集合的所有组合情况
5.1.2 连接查询:内连接、外连接、自连接
自连接 :当前表与自身的连接查询,自连接必须使用别名;
5.1.2.1 内连接(隐式内连接、显示内连接): 相当于查询A、B交集部分数据
1. 隐式内连接
sql
select 字段列表 from 表1,表2 where 条件 ......;
2. 显式内连接 : inner 可以省略
sql
select 字段列表 from 表1 [inner] join 表2 on 条件 ......;
3.内连接的示例演示(隐式内连接/显式内连接)
sql
# 示例:查询每个员工的姓名、及关联的部门名称;
# 隐式内连接
select e.name, d.name from emp e, dept d where e.dept_id = d.id;
# 显式内连接
select e.name, d.name from emp e inner join dept d on e.dept_id = d.id;
5.1.2.2 外连接:(左外连接、右外连接)'outer'可以省略
1. 左外连接:查询左表所有数据,以及两张表交集部分数据
sql
select 字段列表 from 表1 left [outer] join 表2 on 条件......;
# 查询表1(即:左表)所有的数据,包含表1和表2交集部分的数据
2. 右外连接:查询右表所有数据,以及两张表交集部分数据
sql
select 字段列表 from 表1 right [outer] join 表2 on 条件......;
# 查询表2(即:右表)所有的数据,包含表1和表2交集部分的数据
3. 外连接的示例演示(左外连接、右外连接)'outer'可以省略
sql
- 查询emp表的所有数据,和对应的部门信息(左外连接)
select e.*, d.name from emp e left outer join dept d on e.dept_id = d.id;
- 查询dept表的所有数据,和对应的员工信息(右外连接)
select e.*, d.* from emp e right outer join dept d on e.dept_id = d.id;
5.1.2.3 自连接:可以是内连接查询、也可是外连接查询
sql
select 字段列表 from 表 别名1 join 表 别名2 on 条件 ......;
1. 内连接的示例演示
sql
- 查询员工及 其所需领导的名字(因为领导也在员工表,所以使用自连接)
select e1.* , e2.name '直属领导' from emp e1 join emp e2 on e1.managerid = e2.id;
- 查询员工emp 及其领导的名字emp 如果员工没有领导,也需要查询出来;(使用左外连接)
select e1.* , e2.name '直属领导' from emp e1 left join emp e2 on e1.managerid = e2.id;
5.1.3 联合查询、子查询
5.1.3.1 联合查询(union,union all):把多次查询的结果合并,形成一个新的查询结果集;
sql
select 字段列表 from 表1 ......
union [all]
select 字段列表 from 表2 ......;
注意:联合查询的多张表的列数必须保持一致,字段类型也需要保持一致;
union 将多次查询结果合并,去重;
union all 将多次查询结果合并,合并后可能会有重复数据;
sql
- 将薪资低于5000的员工,和 年龄大于50的员工全部查询出来;
select * FROM emp where emp.salary<5000
union
select * from emp where emp.age >50;
# union 将多次查询结果合并,去重;
# union all 将多次查询结果合并,合并后可能会有重复数据;
5.1.3.2 子查询:SQL语句中嵌套select语句,称为嵌套查询,又称子查询;
1. 子查询语法
sql
select * from t1 where column1 = (select column1 from t2);
# 子查询外部的语句可以是insert、update、delete、select的任何一个;
2. 根据子查询结果不同,分为如下:
- 标量子查询(子查询结果为单个值):如:数字、字符串、日期等,常用操作符 =、>、>=、<、<=、<>
- 列子查询(子查询结果为一列,可以是多行):常用操作符:in、not in 、any、some、all
- 行子查询(子查询结果为一行,可以是多列): 常用操作符:=、<>、in、not in
- 表子查询(子查询结果为多行多列):常用操作符:in
sql
**---------标量子查询-------------------------------------------**
# 1. 查询销售部的所有员工
select * from emp where dept_id = (select id from dept where name = '销售部');
# 2. 查询在'王林'入职之后的员工信息
select * from emp where entrydate > (select entrydate from emp where name = '王林');
**---------列子查询-------------------------------------------**
# 1. 查询"销售部"和"市场部"的所有员工信息
select * from emp where emp.dept_id in (select id from dept where name='市场部' || name='销售部');
# 2. 查询比财务部工资都高的所有员工信息 ,使用操作符 all
select * from emp where salary > all(
select salary from emp where dept_id = (
select id from dept where name='财务部'
));
# 3. 查询比研发部其中任意一人工资高的员工信息,使用操作符 any / some
select * from emp where salary > any (
select salary from emp where dept_id = (
select id from dept where name='研发部'
));
**---------行子查询-------------------------------------------**
# 1. 查询与'张无忌'一样工资和直属领导 的员工信息;
select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '张无忌');
**---------表子查询-------------------------------------------**
# 1. 查询与'张无忌'或 '王林'一样职位和薪资 的员工信息;使用操作符 in
select * from emp where (job,salary) in (select job,salary from emp where name ='张无忌'or name = '王林');
# 2. 查询入职时间'2020-01-01'之后的员工,及其部门信息;(这里在from后面使用了子查询)
select * from (select * from emp where entrydate>'2020-01-01' ) e
left join dept d on e.dept_id = d.id;

3. 根据子查询位置,分为:where之后、from之后、select之后;(示例在上一点);
5.1.4 多表查询示例
sql
1.查询员工的姓名、年龄、职位、部门信息。
select e.name,e.age,e.job,d.name from emp e left join dept d on e.dept_id=d.id;
2.查询年龄小于30岁的员工姓名、年龄、职位、部门信息。
select e.name,e.age,e.job,d.name from(select * from emp where age < 30) e left join dept d on e.dept_id=d.id;
3.查询拥有员工的部门ID、部门名称。
select d.id, d.name from dept d where d.id in (select e.dept_id from emp e);
4.查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来;
select * from (select * from emp where age>40 ) e left join dept d on e.dept_id=d.id;
5.查询所有员工的工资等级。
select name,salary,(CASE
WHEN salary>10000 THEN '高级'
WHEN salary>5000 THEN '中级'
WHEN salary>1000 THEN '低级'
ELSE '垃圾'
END) '工资等级'
from emp ;
6.查询"研发部"所有员工的信息及正资等级。
select name,salary,(CASE
WHEN salary>10000 THEN '高级'
WHEN salary>5000 THEN '中级'
WHEN salary>1000 THEN '低级'
ELSE '垃圾'
END) '工资等级' from emp where dept_id = (SELECT id FROM dept WHERE name='研发部')
7.查询"研发部"员工的平均工资。
select avg(salary) from emp where dept_id = (SELECT id FROM dept WHERE name='研发部')
8.查询工资比"张无忌"高的员工信息。
select * from emp where salary > (SELECT salary FROM emp WHERE name='张无忌');
9.查询比平均薪资高的员工信息。
select * from emp where salary > (SELECT avg(salary) FROM emp );
10.查询低于本部门平均工资的员工信息。
select * FROM emp e2 where e2.salary < ( select avg(e1.salary) from emp e1 WHERE e1.dept_id = e2.dept_id)
6. 事务:四大特性、分类、其提交方式修改、开启事务、提交事务、回滚事务
bash
#事务的特性
1.原子性:一个事务不可分割,要么都执行,要么都不执行
2.一致性:一个事务执行会使数据从一个一致状态切换到另一个一致状态
3.隔离性:一个事务不受其他事务的干扰
4.永久性:一个事务的提交,则会永久的改变数据库的数据
#分类:
隐式事务:事务没有明显的开启和结束的标记(如:一般的update\insert\delete等)
显式事务:具有明显的开启和结束的标记
6.1.1 查询并修改事务的提交方式(自动提交、手动提交)(Mysql默认自动、Oracle默认手动)
6.1.1.1 查询并设置事务的提交方式
sql
查询事务的提交方式:
select @@autocommit;
使用显式事务,前提是要禁用自动提交功能,就是设置autocommit变量值为0(0:禁用 1:开启)
set @@autocommit = 0
6.1.1.2 提交事务、回滚事务
sql
步骤1:开启事务:start stransaction 或者 begin;
set @@autocommit = 0;注意:设置为0后,事务不commit,sql就不会永久生效;
start stransaction;#这句可以不写
步骤2:编写事务中的sql语句(select、insert、update、delete)
语句1;
savepoint 保存点名称
语句2;
......
步骤3:结束事务
commit;#提交事务
如果操作出错:需要回滚事务:rollback
或者:rollback to 保存点名称;#回滚事务至保存点名称
6.1.1.3 手动提交事务的效果-示例:
窗口一 :开启事务(已设置为手动提交)、插入两条数据、当前窗口可以查询(但是事务没有手动提交,其他窗口是查询不到最新数据的)

此时在窗口二 :查看最新数据,不会包含最新的两条数据(因为窗口一 的操作事务还没有commit)

在窗口一 :手动提交事务

这样在窗口二 就可以查看最新的插入的两条数据了

6.1.2 并发事务问题

注释1:脏读

注释2:不可重复读

注释3:幻读

6.1.3 事务的隔离级别,及不同隔离级别解决了并发事务的问题(√表示会发生、×表示不会发生)
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| Read uncommitted | √ | √ | √ |
| Read committed(oracle默认) | × | √ | √ |
| Repeatable Read(mysql默认) | × | × | √ |
| Serializable | × | × | × |
事务的隔离级别与数据库性能相互制衡(要根据业务权衡选择的隔离级别)如:
Read uncommitted 隔离级别 数据库性能高,但是数据安全性最差;
Serializable 隔离级别 数据库安全性最高,但数据库性能最差。
6.1.3.1 事务的隔离级别的查看、设置
sql
--查看事务隔离级别
select @@transaction_isolation;
--设置事务隔离级别
set [session|global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}