基础篇 | 进阶篇 | 运维篇 |
---|---|---|
MySQL概述 | 存储引擎 | 日志 |
SQL | 索引 | 主从复制 |
函数 | SQL优化 | 分库分表 |
约束 | 视图/存储过程/触发器 | 读写分离 |
多表查询 | 锁 | |
事务 | InnoDB核心 | |
MySQL管理 |
1 基础篇—MYSQL概述
一、数据库相关概念
名称 | 全称 | 简称 |
数据库 | 存储数据的仓库,数据是有组织的进行存储 | Database(DB) |
数据库管理系统 | 操作和管理数据库的大型软件 | Database Management System(DBMS) |
SQL | 操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准 | Structured Query Language(SQL) |
1)主流的关系型数据库管理系统(实际与现实时间作为参考)
2)总结
1. 数据库
数据存储的仓库
2. 数据库管理系统
操纵和管理大型数据库的软件
3. SQL
操作关系型数据库的编程语言,是一套标准
二、MySQL数据库
1)版本
MySQL官方提供两种不同的版本:
· 社区版(MySOL Community Server)
免费,MySQL不提供任何技术支持
· 商业版(MySQL Enterprise Edition)
收费,可以试用30天,官方提供技术支持
2)下载
下载地址:https://dev.mysql.com/downloads/installer/
* 安装教程可查看资源中给出的图片教程和视频教程。
启动
MySQL80是你安装时起的名字。
NET START MYSQL80
停止
NET STOP MYSQL80
客户端连接
方式一:MySQL提供的客户端命令工具
方式二:系统自带的命令行工具执行指令
Windows系统中cmd连接,快捷键(win+R)
中括号中-h代表的是连接哪一个IP,-p是连接哪一个端口,这两个可以省略,默认连接的就是本机的3306;-u代表的是用户名,-p代表的是你安装时设置的密码。
mysql [-h 127.0.0.1] [-p 3306] -u root -p
3)关系型数据库(RDBMS)
——概念:建立在关系模型基础上,由多张表相互连接的二维表组成的数据库
特点:
1. 使用表存储数据,格式统一,便于维护
2. 使用SQL语言操作,标准统一,使用方便
数据模型
4)总结
1. MySQL下载及安装
——社区版
2. MySQL启动和停止
net start mysql80
net stop mysql80
3. MySQL客户端链接
MySQL自带的客户端命令行
mysql -uroot -p ——需要设置path的环境变量
4. MySQL数据模型
数据库
表
三、SQL
1)SQL的通用语法
1.SOL语句可以单行或多行书写,以分号结尾。
2. SQL语句可以使用空格/缩进来增强语句的可读性。
3. MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
4. 注释:
单行注释:--注释内容 或 # 注释内容(MySQL特有)
多行注释:/*注释内容 */
2)SQL分类
分类 | 全称 | 说明 |
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库、表、字段) |
DML | Data Manipulation Language | 数据操作语言,用来对数据表中的数据进行增删改 |
DQL | Data Query Language | 数据查询语言,用来查询数据库中表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
3)DDL
DDL——数据库操作
☛ 查询
查询所有数据库
SHOW DATABASES;
查询当前数据库
SELECT DATABASE;
☛ 创建
CREATE DATABASE[IF NOTEXISTS] 数据库名 [DEFAULT CHARSET字符集] [COLLATE 排序规则];
☛ 删除
DROP DATABASE [IF EXISTS] 数据库名;
☛ 使用
USE 数据库名;
DDL-表操作-查询
☛ 查询当前数据库所有表
SHOW TABLES;
☛ 查询表结构
DESC 表明;
☛ 查询指定表的建表语句
SHOW CREATE TABLE 表名;
DDL-表操作-创建
CREATE TABLE 表名(
字段1 字段1类型 [COMMENT 字段1注释],
字段2 字段2类型[COMMENT 字段2注释],
字段3 字段3类型[COMMENT 字段3注释],
...
字段n 字段n类型[COMMENT 字段n注释] ←
)[COMMENT 表注释];
注意:[...]为可选参数,最后一个字段后面没有逗号(所有的逗号都是英文逗号)
DDL-表操作-数据类型
MySQL中的数据类型有很多,主要分为三类:数值类型、字符串类型、日期时间类型。
数值类型
分类 | 类型 | 大小 | 有符号(SIGNED)范围 | 无符号(UNSIGNED)范围 | 描述 |
数值类型 | TINYINT | 1 byte | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 bytes | (-32768,32767) | (0,65535) | 大整数值 | |
MEDIUMINT | 3 bytes | (-8388608,8388607) | (0,16777215) | 大整数值 | |
INT或INTEGER | 4 bytes | (-2147483648,2147483647) | (0,4294967295) | 大整数值 | |
BIGINT | 8 bytes | (-2^63,2^63-1) | (0,2^64-1) | 极大整数值 | |
FLOAT | 4 bytes | (-3.402823466 E+38,3.402823466351 E+38) | 0 和 (1.175494351 E-38,3.402823466 E+38) | 单精度浮点数值 | |
DOUBLE | 8 bytes | (-1.7976931348623157 E+308,1.7976931348623157 E+308) | 0 和 (2.2250738585072014 E-308,1.7976931348623157 E+308) | 双精度浮点数值 | |
DECIMAL | 依赖于M(精度)和D(标度)的值 | 依赖于M(精度)和D(标度)的值 | 小数值(精确定点数) |
字符串类型
分类 | 类型 | 大小 | 描述 |
字符串类型 | CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 | |
TINYBLOB | 0-255 bytes | 不超过255个字符的二进制数据 | |
TINYTEXT | 0-255 bytes | 短文本字符串 | |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 | |
TEXT | 0-65 535 bytes | 长文本数据 | |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 | |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 | |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 | |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
日期时间类型
分类 | 类型 | 大小 | 范围 | 格式 | 描述 |
日期类型 | DATE | 3 | 1000-01-01 至 9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | -838:59:59 至 838:59:59 | HH:MM:SS | 时间值或持续时间 | |
YEAR | 1 | 1901 至 2155 | YYYY | 年份值 | |
DATETIME | 8 | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 | |
TIMESTAMP | 4 | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |
练习——根据需求创建表(设计合理的数类型、长度)
设计一张员工信息表,要求如下
1. 编号(纯数字)
2. 员工工号(字符串类型,长度不超过10位)
3. 员工姓名(字符串类型,长度不超过10位)
4. 性别(男/女,存储一个汉字)
5. 年龄(正常人年龄,不可能存储负数)
6. 身份证号(二代身份证号均为18位,身份证中有X这样的字符)6.
7. 入职时间(取值年月日即可)
DDL-表操作-修改
☛ 添加字段
ALTER TABLE 表名 ADD 字段名 类型(长度) [comment 注释] [约束];
☛ 修改数据类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
☛ 修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [comment 注释] [约束];
☛删除字段
ALTER TABLE 表名 DROP 字段名;
☛修改表名
ALTER TABLE 表名 RENAME TO 新表名;
DDL-表操作-删除
DROP TABLE [IF EXISTS] 表名;
☛删除指定表,并重新创建该表
TRUNCATE TABLE 表名;
总结
① DDL—数据库操作
SHOW DATABASES; 查看当前有哪些数据库
CREATE DATABASE 数据库名; 创建数据库
USE 数据库名; 切换/使用某个数据库
SELECT DATABSE(); 查看当前在哪个数据库下
DROP DATABASE 数据库名; 删除数据库
② DDL—表操作
SHOW TABLES; 查看当前数据库所有表
CRETAE TABLE 表名 (字段 字段类型, 字段, 字段类型); 创建表
DESC 表名; 查询表
SHOW CRETAE TABLE 表名; 查询表的建表语句
ALTER TABLE 表名 ADD/MODIFY/CHANGE/RENAME TO...; 表结构修改
DROP TABLE 表名; 删除表
MySQL图形化界面
看个人选择,这边俺用到的是Datagrip。
我的资源有2020版的安装包,想要最新的也可以去到官网下载:
官网链接:https://www.jetbrains.com.cn/en-us/datagrip/https://www.jetbrains.com.cn/en-us/datagrip/
下载完成之后,双击打开,路径自己想放哪就放哪,随后点击Next下一步。
选择在桌面创建一图标。
默认下一步,开始Install下载。
安装完之后,点击图中的Run DataGrip,运行程序。
打开后会问我们是否要导入配置,第一次下载没有的话就选择第二个 Don not就好了。
进来后,默认是下图,但我们要点击图中红色框框的免费试用。
选择第一个,建立一个新的项目,名字看个人自取。
进来之后,连接数据库
配置MySQL的连接信息,并且下载他的驱动
用户密码,自己设置。(设置的用户密码就是之后连接数据库的用户密码,不要忘记了)
下载驱动好了之后,点击test connetion测试连接,能显示Succeeded就说明成功了,然后点击OK就完成了。
下载完之后会提示我们可以点击那三个点来显示其他的数据库(schemas指的就是数据库)
点击之后会显示很多,你只要点击All schemas所有数据库就可以了,随后点击刷新就会出现了。
这样datagrip图形化界面就安装好了,如操作过程中有不同的地方,就去B站搜索找找资源看看吧,哈哈。
4)DML
DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的记录进行增、删、改操作。
☛ 添加数据(INSERT)
☛ 修改数据(UPDATE)
☛ 删除数据(DELETE)
DML—添加数据
☛ 给指定的字段添加数据
INSERT INTO 表名(字段名1,字段2名,...) VALUES(值1,值2,...);
☛给全部的字段添加数据
INSERT INTO 表名 VALUES(值1,值2,...);
☛批量添加数据
INSERT INTO 表名(字段名1,字段名2) VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
INSERT INTO 表名 VALUES(值1,值2,...),(值1,值2,...),(值1,值2,...);
注意 :
· 插入数据时,指定字段顺序需要与值的顺序是一 一对应的
· 字符串和日期型数据应该包含在引号中
· 插入数据的大小,应该在字段的规定范围内
DML—修改数据
UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2,...[WHERE 条件]
注意:修改条件可以有,也可以没有,如果没有,则修改的是整张表的所有数据
DML—删除数据
DELETE FROM 表名 [WHERE 条件];
注意: DELATE语句条件可以有,也可以没有,如果没有,则删除的是整张表的所有数据
DELETE语句不能删除某一个字段的值(可以使用UPDATE)
总结
① 添加数据
INSERT INTO 表名(字段名1, 字段名2) VALUES(值1, 值2, ...)[, (值1, 值2, ...)];
②修改数据
UPDATE 表名 SET 字段1 = 值1, 字段2 = 值2 [ WHERE 条件 ];
③删除数据
DELETE FROM 表名 [ WHERE 条件 ];
5) DQL
全称Data Query Language(数据查询语句),数据查询语言,用来查询数据库中表的记录。
查询关键字:SELECT
DQL—语法
SELECT
字段列表
FROM
表名列表 · 基本查询
WHERE · 条件查询 (WHERE )
条件列表 · 聚合函数( COUNT、MAX、MIN、AVG、SUM)
GROUP BY · 分组查询( GROUP BY )
分组字段列表 · 排序查询( ORDER BY )
HAVING · 分页查询( LIMIT )
分组后查询列表
ORDER BY
排序字段列表
LIMIT
分页查询
DQL—基本查询
☛查询多个字段
SELECT 字段1, 字段2, 字段3, FROM 表名;
SELECT * FROM 表名; 查询所有字段, * 代表所有字段
☛设置别名
SELECT 字段1 [ AS 别名1 ], 字段2 [ AS 别名2 ] ... FROM 表名; 在语法中,AS可以省略
☛去除重复记录
SELECT DISTINCT 字段列表 FROM 表名;
DQL—条件查询
①语法
SELECT 字段列表 FROM 表名 WHERE 条件列表;
②条件
比较运算符 | 功能 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
= | 等于 |
<> 或 != | 不等于 |
BETWEEN...AND... | 在某个范围之类(含最小、最大值) |
IN( ... ) | 在IN之后的列表中的值,多选一 |
LIKE 占位符 | 模糊匹配( _ 匹配单个字符串,%匹配任意字符串) |
IS NULL | 是NULL(空值) |
逻辑运算符 | 功能 |
---|---|
AND 或 && | 并且(多个条件同时成立) |
OR 或 || | 任意(多个条件任意一个成立) |
NOT 或 ! | 非, 不是 |
DQL—聚合函数
将一列数据作为一个整体,进行纵向计算。
—常见的聚合函数
函数 | 功能 |
---|---|
COUNT | 统计数量 |
MAX | 最大值 |
MIN | 最小值 |
AVG | 平均值 |
SUM | 求和 |
语法
SELECT 聚合函数(字段列表) FROM 表名;
注意:NULL值不参与所有聚合函数运算
DQL—分组查询
☛语法
SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组过滤后条件];
where 与 having区别
☛ 执行时机不同::where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。
☛ 判断条件不同:where不能对聚合函数进行判断,而having可以。
注意:
· 执行顺序:where > 聚合函数 > having
· 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
DQL—排序查询
☛语法
SELECT 字段列表 FROM 表名 ORDER BY 字段列表1 排序方式1, 字段列表2 排序方式2;
排序方式:
ASC:升序(默认值)
DESC:降序
注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序
DQL—分页查询
☛语法
SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数;
注意:
起始索引从0开始,起始索引=(查询页码 - 1)*每页显示记录数。
分页查询是数据库的方言,不同的数据库有不同的体现,MySQL中的LIMIT。
如果查询的是第一页数据,起始索引可以忽略,直接简写成LIMIT 10。
-- -查询第1页员工的数据,每页展示10条记录
SELECT * FROM EMP LIMIT 0, 10; -- 因为第一页是起始页,说以是0(查询页码 - 1)
-- -查询第2页员工的数据,每页展示10条记录
SELECT * FROM EMP LIMIT 1, 10; -- 第二页就是1,(查询页码 - 1)
案例演练(自行创表演练)
按照需求完成如下DQL语句编写:
① 查询年龄为20,21,22,23岁的员工信息。
② 查询性别为 男 ,并且年龄在 20-40 岁(含)以内的姓名为三个字的员工。
③ 统计员工表中,年龄小于60岁的,男性员工和女性员工的人数。
④ 查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序。
⑤ 查询性别为男,且年龄在20-40 岁(含以内的前5个员工信息,对查询的结果按年龄升序排序,年龄相同按入职时间升序排序。
DQL—执行顺序
编写顺序:
SELECT ④
字段列表
FROM ①
表名列表
WHERE ②
条件列表
GROUP BY ③
分组字段列表
HAVING
分组后查询列表 ⑤
ORDER BY
排序字段列表
LIMIT ⑥
分页查询
执行顺序:
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段列表
HAVING
分组后条件列表
SELECT
字段列表
ORDER BY
排序字段列表
LIMIT
分页查询
总结
DQL—语句
SELECT
字段列表 字段名 [ AS ] 别名
FEOM
表名
WHERE
条件查询 > >= < <= = <> like between...and... in and or
分组之前过滤
GROUP BY
分组字段列表
HAVING
分组后条件查询 分组之后过滤
ORDER BY
排序字段列表 升序 ASC ,降序DESC
LIMIT
分页参数 起始索引(从0开始),每页展示记录
6)DCL
DCL的英文全称是Data Control Language(数据控制语言),用来管理数据库 用户、控制数据库的访问权限。
DCL—管理用户
☛查询用户
USE Mysql;
SELECT * FROM user;
☛创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
-- 创建用户 JAY ,只能在当前主机localhost访问,密码123456;
create user 'JAY'@'localhost' identified by '123456';
-- 创建用户 Tom ,可以在任意主机访问该数据库,密码123456;
create user 'Tom'@'%' identified by '123456'; -- % 代表任意主机
☛修改密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码';
☛删除用户
DROP USER '用户名'@'主机名';
注意:
——主机名可以使用 % 通配。
——这类SQL开发人员操作的比较少,主要是DBA(Database administrator 数据库管理员),使用
DCL—权限控制
MySQL中定义了很多权限,但是常用的就是一下几种;
权限 | 说明 |
---|---|
ALL,ALL PRIVILEGES | 所有权限 |
SELECT | 查询数据 |
INSERT | 插入数据 |
UPDATA | 修改数据 |
DELETE | 删除数据 |
ALTER | 修改表 |
DROP | 删除数据库/表/视图 |
CREATE | 创建数据库/表 |
其他权限描述及含义,可直接 参考官方文档:https://dev.mysql.com/doc/refman/8.3/en/
☛查询权限
SHOW GRANTS FOR '用户名'@'主机名';
☛授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
☛撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
注意:
——多个权限之间使用逗号分隔
——授权时,数据库名和表名可以使用 * 进行通配,代表所有
总结
①用户管理
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '密码';
DROP USER '用户名'@'主机名';
②权限控制
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
四、函数
含义:函数是指一段可以直接被另一个程序调用的程序或者代码
·字符串函数
·数值函数
·日期函数
·流程函数
字符串函数
函数 | 功能 |
---|---|
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个长度的字符串 |
SELECT 函数(参数);
举例说明,拿 SUBSTRING 作参考;
练习:
由于公司业务需求变更,企业员工的工号同一位6位数,不足6位数的全部在前面补0。比如:1号员工的工号应该为000001。
数值函数
常见的数值函数如下:
函数 | 功能 |
---|---|
CEIL(x) | 向上取整 |
FLOOR(x) | 向下取整 |
MOD(x, y) | 返回x/y的模 |
RAND() | 返回0~1内的随机数 |
ROUND(x, y) | 求参数x的四舍五入的值,保留y位小数 |
举例说明:
练习:通过数据库函数,随机生成一个6位数的随机验证码。
日期函数
常见的日期函数如下:
函数 | 功能 |
---|---|
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语句中实现条件筛选,从而提高语句的效率。
函数 | 功能 |
---|---|
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默认值 |
示例:
练习:
-- 案例:统计班级各个学员的成绩,展示的规则如下: -- >= 85,展示优秀 -- >= 60,展示及格 -- 否则,展示不及格
总结
①字符串函数
CONCAT, LOWER, UPPER, LPAD, RPAD, TRIM, SUBSTRING
②数值函数
CEIL, FLOOR, MOD, RAND, ROUND
③日期函数
CURDATE, CURTIME, NOW, YEAR, MONTH, DAY, DATE_ADD, DATEDIFF
④流程函数
IF, IFNULL, CASE [...] WHEN ... THEN ...ELSE ... END
五、约束
· 概述
· 约束演示
· 外键约束
概述
——约束是作用于表字段上的规则,用于限制存储在表中的数据。
目的:保证数据库中数据的正确性、有效性和完整性。
分类:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
检查约束(8.0.16版本之后) | 保证字段值满足某一条件 | CHECK |
外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | FOREING KEY |
注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
约束演示
根据需求,完成表结构的创建:
字段名 | 字段含义 | 字段类型 | 约束条件 | 约束关键字 |
---|---|---|---|---|
id | 唯一标识符 | int | 主键并且自动增长 | PRIMARY KEY, AUTO_INCREMENT |
name | 姓名 | varchar(10) | 不为空,并且唯一 | NOT NULL, UNIQUE |
age | 年龄 | int | 大于0,并且小于等于120 | CHENK |
status | 状态 | char(1) | 如没有指定该值,默认为1 | DEFAULT |
gender | 性别 | char(1) | 无 |
create table user(
id int primary key auto_increment comment '主键',
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 '用户表';
外键约束
1)概念:外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。
注意:目前上述的两张表,在数据库层面,并未建立外键关联,所以是无法保证数据的一致性和完整性的。
2)语法:
☛添加外键
① 创建表时直接添加
CREATA TABLE 表名(
字段名, 数据类型,
...
[CONSTRAING] [外键名称] FOREIGN KEY (外键字段名) REFERENCES (主表) (主表列名)
);
②表创建好后,额外增加
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES (主表) (主表列名)
☛删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
3)删除/更新行为
行为 | 说明 |
---|---|
NO ACTION | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与RESTRICT一致) |
RESTRICT | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 NO ACTION 一致) |
CASCADE | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。 |
SET NULL | 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为nul(这就要求该外键允许取nu) |
SET DEFAULT | 父表有变更时,子表将外键列设置成一个默认的值(Innodb不支持) |
ALTERTABLE 表名 ADD CONSTRAINT 外键名称 FOREIGNKEY(外键字段) REFERENCES 主表名(主表字段名)ON UPDATE CASCADE ON DELETE CASCADE;
总结
1.非空约束:NOT NULL
2.唯一约束:UNIQUE
3.主键约束:PRIMARY KEY(自增:AUTO INCREMENT)
4.默认约束:DEFAULT4.
5.检查约束:CHECK
6.外键约束:FOREIGN KEY
六、多表查询
· 多表关系
· 多表查询概述
· 内连接
· 外连接
· 自连接
· 子查询
· 多表查询案例
多表关系
概述:
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:
一对多(多对一)
多对多
一对一
① 一对多(多对一)
案例:部门 与 员工的关系
关系:一个部门对用多个员工,一个员工对应一个部门
实现:在多的一方建立外键,指向一的一方的主键
② 多对多
案例:学生 与 课程的关系
关系:一个学生可以选修多门课程,一门课程也可以供多名学生选择
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两张主键
③ 一对一
案例:用户 与 用户详情的关系
关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。
关系:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
多表查询概述
概述:从多张表中查询数据
笛卡尔积:笛卡尔乘积是指在数学中,两个集合,A集合 和 B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)
多表查询分类:
连接查询
内连接:相当于查询A、B交集部分数据
外连接:
左外连接 :查询左表的所有数据,以及两张表交集部分数据
右外连接:查询右表的所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
子查询:
内连接
连接查询-内连接
内连接查询语法:
☛隐式内连接
SELECT 字段列表 FROM 表1, 表2 WHERE 条件 ...;
☛显式内连接
SELECT 字段列表 表1 [ INNER ] JOIN 表2 ON 连接条件 ... ;
内连接查询的是两张表交集的部分
外连接
连接查询—外连接
☛左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件 ... ;
* :相当于查询表1(左表)的所有数据,包含表1 和 表2的交集部分
☛ 右外连接
SELECT 字段列表 FROM 表1 [OUTERRIGHT] JOIN 表2 ON 条件 ... ;
* :相当于查询表1(右表)的所有数据,包含表1 和 表2的交集部分
自连接
连接查询—自连接
☛自连接的查询语法
SELECT 字段列表 FROM 表A 别名A JOIN 表B 别名B ON 条件 ... ;
* :自连接查询,可以是内连接查询,也可以是外连接查询
联合查询—UNION, UNION ALL
对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
SELECT 字段列表 FROM 表A ... ;
UNNION [ALL]
SELECT 字段列表 FROM 表B ... ;
* :对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致
union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重
子查询
1)概念:SQL语句中嵌套SELECT语句,称为 嵌套查询,又称 子查询。
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
2)根据子查询结果不同,分为:
☛标量子查询(子查询结果为单个值)
☛列子查询(子查询结果为一列)
☛行子查询(子查询结果为一行)
☛表子查询(子查询结果为多行多列)
3)根据子查询位置,分为:WHERE之后,FROM之后,SELECT之后。
① 标量子查询:
子查询返回的结果是单个值(数字、字符串、日期等)最简单的形式,这种子查询称为标量子查询。
——常用操作符:= <> > >= < <=
② 列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
——常用操作符:IN、NOT IN、ANY、SOME、ALL
操作符 | 描述 |
---|---|
IN | 在指定的范围内多选一 |
NOT IN | 不在指定的范围之内 |
ANY | 子查询返回列表中,有任意一个满足即可 |
SOME | 与ANY等同,使用SOME的地方都可以使用ANY |
ALL | 子查询返回列表的所有值都必须满足 |
③ 行子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
——常用操作符: =、<>、IN、NOT IN
④ 表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询。
——常用操作符:IN
多表查询案例
1.查询员工的姓名、年龄,职位,部门信息(隐式内连接)
-- 表:emp, dept -- 连接条件: emp.dept_id = dept.idselect e.name, e.age, e.job, d.name from emp e, dept d where e.dept_id = d.id;
2.查询年龄小于30岁的员工的姓名、年龄、职位、部门信息(显式内连接)
-- 表:emp, dept -- 连接条件: emp.dept_id = dept.id select e.name, age, job, d.name from emp e join dept d on e.dept_id = d.id where e.age < 30;
3. 查询拥有员工的部门ID、部门名称
-- 表:emp, dept -- 连接条件: emp.dept_id = dept.id select distinct d.id, d.name -- distinct(去除重复) from emp e, dept d where e.dept_id = d.id order by id;
4. 查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展现出来
-- 表:emp, dept -- 连接条件: emp.dept_id = dept.id select e.*, d.name from emp e left join dept d on e.dept_id = d.id where e.age > 40;
5. 查询所有员工的工资等级
-- 表:emp salgrade -- 连接条件:emp.salary >= salgrad.losal and emp.salary <= salgrad.hisal select e.* from emp e, salgrade s where e.salary >= s.losal and e.salary <= s.hisal;select e.*, s.grade, s.losal, s.hisal from emp e, salgrade s where e.salary between s.losal and s.hisal;
6.查询 ‘研发部’ 所有员工的信息及 工资等级
-- 表:emp salgrade dept -- 连接条件:emp.salary between salgrad.losal and salgrad.hisal emp.dept_id = dept.id -- 查询条件:dept.name = '研发部' select e.*, s.losal, s.hisal, d.name from emp e, dept d, salgrade s where e.dept_id = d.id and e.salary between s.losal and s.hisal and d.name = '研发部' order by e.id;
7. 查询 ‘研发部’ 员工的平均工资
-- 表:emp, dept -- 连接条件: emp.dept_id = dept.id select avg(salary) from emp e, dept d where e.dept_id = d.id and d.name = '研发部';
8. 查询工资比 ‘灭绝’ 高的员工信息
-- a 查询 ‘灭绝’的工资 select salary from emp where name = '灭绝'; -- b 查询比他高的员工数据 select * from emp where salary > ( select salary from emp where name = '灭绝' );
9. 查询比平均薪资高的员工信息
-- a 查询员工的平均薪资 select avg(salary) from emp; -- b 高于平均薪资的员工信息 select * from emp where salary > ( select avg(salary) from emp );
10. 查询低于本部门的平均工资的员工信息
-- a 查询指定部门的平均薪资 select avg(salary) from emp e where e.dept_id = 1; select * from emp where salary < ( select avg(salary) from emp e where e.dept_id = 1 );
11. 查询所有部门信息,并统计部门员工的员工人数
select distinct d.id, d.name, ( select count(*) from emp e where e.dept_id =d.id )'人数' from emp e, dept d order by id; select COUNT(*) from emp where dept_id = 1;
12. 查询所有学生的选课情况,展示出学生名称,学号,课程名称。
-- 表:student, coures, student_coures -- 连接条件:student.id = student_coures.studentid, coures.id = student_courees.couresid select s.name, s.xueh, c.name from student s, student_course sc, course c where s.id = sc.studentid and sc.courseid = c.id;
总结
1.多表关系
一对多:在多的一方设置外键,关联 一 的一方的主键
多对多:建立中间表,中间表包含两个外键,关联两张表的主键
一对一:用于表结构的拆分,在其中任何一方设置外键
2. 多表查询
内连接
隐式:SELECT...FROM 表A,表B WHERE 条件...
显示:SELECT...FROM 表A INNER JOIN 表B ON 条件...
外连接
左外:SELECT...FROM 表A LEFT JOIN 表B ON 条件...
右外:SELECT...FROM 表A RIGHT JOIN 表B ON 条件...
自连接:SELECT...FROM 表A 别名1, 表A 别名2 WHERE 条件...
子查询:标量子查询、列子查询、行子查询、表子查询
七 事务
· 事务简介
· 事务操作
· 事务四大特征
· 并发事务问题
· 事务隔离级别
事务简介
事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
银行取钱举例说明:
正常情况下:
张三(女),李四(男);张三要转账1000元给李四,首先要查看余额是否又足够的资金。
查看到有足够的钱之后,张三就转账给李四,自身的余额就-1000了。
然后李四的账户就增加了1000了。
异常情况:
第一步,同上,查询张三账户余额。
第二步,转账给李四1000,张三的余额-1000
到了第三步时,本应该李四的账户会+1000,但是由于程序异常,导致不仅李四账户没增加,反而张三的余额还是相应的扣除了1000元。
从上述介绍就清楚的知道了事务的简介了,要么同时成功,要么同时失败,如果失败了,就会回滚事务(指的就是把之前临时修改的数据恢复成原来的数据),这样也保证了这些操作要么同时成功,要么同时失败,从而保证了数据的完整性和一致性。
* 默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。
事务操作
☛ 查看/设置事务方式
SELECT @@autocommit;
SET @@autocommit = 0;
☛ 提交事务
COMMIT;
☛ 回滚事务
ROLLBACK;
☛开启事务
START TRANSACTION 或 BEGIN;