【超级详细的Mysql入门到进阶】

Mysql进阶

1.SQL分类

【MySQL】SQL的分类 DDL、DML、DQL、DCL

  1. DDL(Data Definition Language,数据定义语言)

    主要用于维护存储数据的结构,这种结构包括数据库,表、视图、索引、同义词、聚簇等。

    代表指令:

    • create 创建数据库和数据库的一些对象
    • drop 删除数据库/表、索引、条件约束以及数据表的权限等
    • alter 修改数据库表的定义及数据属性
    • TRUNCATE 清除表
  2. DML(Data Manipulation Language,数据操纵语言)

    主要用于对数据库对象中包含的数据进行操作

    代表指令:

    • insert 向数据库中插入一条数据
    • delete 删除表中的一条或者多条记录
    • updata 修改表中的数据
  3. DQL(Data Query Language,数据查询语言)

    主要用于查询数据库当中的数据

    代表指令:

    • selete 查询表中的数据
    • from 查询哪张表、视图
    • where 约束条件
  4. DCL(Data Control Language,数据控制语言)

    主要控制数据库对象的权限管理事务实时监视

    代表指令:

    • grant分配权限给用户
    • revoke废除数据库中某用户的权限
    • rollback 退回到某一点 (回滚)
    • commit 提交

DDL和DML的说明

​ ①DDL的操作一旦执行,就不可回滚。指令SET autocommit = FALSE对DDL操作失效。(DDL操作完一定有一次commit)
​ ②DML的操作默认情况,一旦执行,也是不可回滚的。但是,如果在执行DML之前,执行了
​ SET autocommit = FALSE,则执行的DML操作就可以实现回滚。

2.MySQL体系结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-heFjNRor-1662295707169)(file:///C:/Users/995281~1/AppData/Local/Temp/b737777e-e84e-40af-b3b0-3f55b3f8d1b4.jpg)]

2.1连接层

最上层是一些客户端和链接服务,主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。

2.2服务层

第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成缓存的查询,SQL的分析和优化,部分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如过程、函数等。

2.3引擎层

存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎。

2.4存储层

主要是将数据存储在文件系统之上,并完成与存储引擎的交互。

3.多表查询的分类

3.1角度1:

等值连接vs非等值连接

3.2角度2:

白连接vs非白连接

3.3角度3:

内连接vs外连接

  • 内连接 :内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行

  • 外连接:合并具有同一列的两个以上的表的行,结果集中除了包含一个表与另一个表匹配的行之外,还查询到了左表或右表中不匹配的行。

    • 左外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回左表中不满足条件的行
    • 右外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回右表中不满足条件的行
    • 满连接:
\# SQL99 语法实现内连接 INNER可省略

SELECT u.name 姓名 ,dep.name 部门, u.salary 工资, g.grade_name  工资等级

FROM users u

INNER JOIN departments dep

on u.dep_id = dep.dep_id

INNER JOIN grade g

on u.salary BETWEEN g.low AND g.high

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-79gOxzSA-1662295707171)(file:///C:/Users/995281~1/AppData/Local/Temp/2a366e60-2097-48d9-b8f5-f195d9064bc3.jpg)]

\#SQL99语法实现左外连接 OUTER可省略

SELECT u.name 姓名 ,dep.name 部门

FROM users u

LEFT OUTER JOIN departments dep

on u.dep_id = dep.dep_id

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tHRLPZRz-1662295707172)(file:///C:/Users/995281~1/AppData/Local/Temp/8ef90aae-1109-469d-a552-c2693526eecd.jpg)]

\#SQL99语法实现右外连接 OUTER可省略

SELECT u.name 姓名 ,dep.name 部门

FROM users u

RIGHT OUTER JOIN departments dep

on u.dep_id = dep.dep_id

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dXskcmf-1662295707172)(file:///C:/Users/995281~1/AppData/Local/Temp/9ded1392-2cbe-48db-9909-d6f724ad993a.jpg)]

4. UNION和UNION ALL联合查询的使用

  1. UNION:会执行去重操作
  2. UNION ALL:不会执行去重操作

结论:如果明确知道合并数据后的结果数据不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效率。

5. 7种SQL JOINS的实现

核心图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xjmuafxg-1662295707173)(file:///C:/Users/995281~1/AppData/Local/Temp/c74059c4-6d4a-47bd-86f9-0d60f2628a62.jpg)]

\#SQL99语法实现右外连接 OUTER可省略 Mysql不支持FULL OUTER JOIN

\#需要把左外和右外进行联合查询

SELECT u.name 姓名 ,dep.name 部门

FROM users u

LEFT OUTER JOIN departments dep

on u.dep_id = dep.dep_id

\#UNION #9条记录 去重会影响效率

UNION ALL #15条记录 不去重 重叠部分会出现2次

SELECT u.name 姓名 ,dep.name 部门

FROM users u

RIGHT OUTER JOIN departments dep

on u.dep_id = dep.dep_id

\#尽量使用 UNION ALL 联合之前 WHERE u.dep_id is NULL去掉重复部分

SELECT u.name 姓名 ,dep.name 部门

FROM users u

LEFT OUTER JOIN departments dep

on u.dep_id = dep.dep_id

UNION ALL 

SELECT u.name 姓名 ,dep.name 部门

FROM users u

RIGHT OUTER JOIN departments dep

on u.dep_id = dep.dep_id

WHERE u.dep_id is NULL

8.函数

8.1单行函数

  1. 数值函数
  2. 字符串函数
  3. 时间类型函数
  4. 流程控制函数
  5. 加密、解密函数
  6. Mysql信息函数

8.2多行函数(聚合函数)

  1. SUN()
  2. COUNT()
  3. AVG()

9. 子查询

问题 :查询比张三工资高的人

  1. 自连接实现
SELECT u2.name,u2.salary
FROM users u1,users u2
WHERE u1.name = '张三'
AND u2.salary > u1.salary
  1. 子查询实现
SELECT name,salary
FROM users
WHERE salary > (
	SELECT salary
	FROM users
	WHERE name='张三'
)

  • 子查询(内查询)在主查询之前一次执行完成。

  • 子查询的结果被主查询(外查询)使用

  • 注意 !

  • 子查询要包含在括号内

  • 将子查询放在比较条件的右侧

  • 单行操作符对应单行子查询,多行操作符对应多行子查询

10. Mysql 8 新特性计算列

CREATE TABLE compute(
a int,
b int,
c int [GENERATED ALWAYS AS] (a+b) [VIRTUAL]
)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Eq0yB2k1-1662295707174)(C:\Users\995281251\AppData\Roaming\Typora\typora-user-images\image-20220902191307414.png)]

11. MySQL中的数据类型

11.1 整数类型

  • TINYINT
  • SMALLINT
  • MEDIUMINT
  • INT INTEGER
  • BIGINT

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BDhJRS8M-1662295707174)(C:\Users\995281251\AppData\Roaming\Typora\typora-user-images\image-20220902192203034.png)]

11.2 浮点数类型

注意!!!

浮点类型的小数,如果不是以0、5结尾无法用二进制精确表达,如:

1.125+1.875=3 没问题 ,但是

  1. FLOAT

  2. DOUBLE

  3. DECIMAL (DECIMAL(5,2) : 表示 总共五位,有两位小数,如666.12)

    DECIMAL 在底层是以字符串类型存储的

  4. BIT( ? ) ?代表二进制的位数

11.3 日期类型

11.4 文本字符类型

  • CHAR(M): 不可变长,可能会浪费空间,但是速度快效率高,比较短的数据且长度固定建议使用,如门牌号(A110,B111等)
  • VARCHAR(M):变长,节省空间,但是没错存储需要额外的计算得到长度,如果经常需要改变不建议使用

情况1∶存储很短的信息。比如门牌号码101,201…这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的,结果得不偿失。
情况2∶固定长度的。比如使用uuid作为主键,那用char应该更合适。因为他固定长度,varchar动态根据长度的特性就消失了,而且还要占个长度信息。
情况3∶十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。
情况4:具体存储引擎中的情况:

①MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。这样使得整个表静态化,从而使数据检索更快,用空间换时间。 ②MENORY存储引擎和数据列:MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的。 ③InnoDB存储引擎,建议使用VARCHAR类型。因为对于InnoDB数据表,内部的行存储格式并没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素是数据行使用的存储总量,由于char平均占用的空间多于varchar,所以除了简短并且固定长度的,其他考虑varchar这样节省空间,对磁盘I/O和数据存储总量比较好。

  • TINYTEXT
  • TEXT
  • MEDIUMTEXT
  • LONGTEXT (最大4GB )

TEXT文本类型,可以存比较大的文本段,搜索速度稍慢,因此如果不是特别大的内容,建议使用CHAR,VARCHAR来代替。还有TEXT类型不用加默认值,加了也没用。而且text和blob类型的数据删除后容易导致"“空洞”,使得文件碎片比较多,所以频繁使用的表不建议包含TEXT类型字段,建议单独分出去,单独用一个表。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggvcS5Vk-1662295707175)(C:\Users\995281251\AppData\Roaming\Typora\typora-user-images\image-20220902215922156.png)]

  • ENUM

    不区分大小写

    只能插入一个、不能插入没有枚举出的

    可以按索引插入 从1开始

INSERT T_ENUM 
VALUES('春'),(2),('unkown') 
  • SET

不区分大小写

能插入多个、不能插入没有枚举出的

可以按索引插入 从1开始

多个元素用逗号隔开,会自动去重

INSERT T_SET
VALUES('吃饭'),('吃饭,写代码'),('吃饭,写代码,写代码')

11.5 二进制类型

  • BINARY

  • VARBINARY(M)

  • TINYBLOG

  • BLOG

  • MEDIUMBLOG

  • LONGBLOG

BLOB是一个二进制大对象,可以容纳可变数量的数据。 MysQL中的BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB4种类型,它们可容纳值的最大长度不同。可以存储一个二进制的大对象I比如图片、音频和视频等。 需要注意的是,在实际工作中,往往不会在MysQL数据库中使用BLOB类型存储大对象数据,通常会将图片、音频和视频文件存储到服务器的磁盘上,并将图片、音频和视频的访问路径存储到MysQL中。

11.6 JOSN类型

JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。简洁和清晰的层次结构使得JSON成为理想t数据交换语言。它易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON可以将JavaScript对象中表示的一组数据转换为字符串,然后就可以在网络或者程序之间轻松地传递这个字符串,并在需要的时候将它还原为各编程语言所支持的数据格式。【在MysQL 5.7中,就已经支持JSON数据类型。在MySQL 8.x版本中,JSON类型提供了可以进行自动验证的JSON文档和优化的存储结构,使得在MysQL中存储和读取JSON类型的数据更加方便和高效。
创建数据表,表中包含一个JSON类型的字段js。

11.7 空间类型


12. 约束(constraint)

如果约束没有指定名字 则默认和字段名字一样

12.1 为什么需要约束

简单来说就是:确保数据完整和有效

12.2 什么叫约束

对表中字段的限制

12.3 约束的分类

约束字段的个数来分

**单例约束 vs 多例约束 **

约束的作用范围来分

列级约束 vs 表级约束

  • 列级约束:将此约束声明在对应字段的后面

  • 表级约束:在表中所有字段都声明完,在所有字段的后面声明的约束

约束的作用来分

  1. not null(非空约束)
  2. unique(唯一性约束)
  3. primary key (主键约束)
  4. foreign key (外键约束)
  5. check(检查约束)
  6. default(默认值约束)

复合唯一约束和复合主键约束只要有其中有一个字段不同即可,复合唯一约束允许存在NULL,复合主键约束不允许存在NULL

复合唯一约束 (unique)

#复合唯一
CREATE TABLE student(
stu_id int NOT NULL, #列级约束
cour_id int,
cour_scores int,

#表级约束
CONSTRAINT uni_stu_sco UNIQUE(stu_id,cour_scores)
)

复合主键约束

主键起别名无用 应为所有主键名字一定为PRIMARY

CREATE TABLE IF NOT EXISTS users1(
account int,
password int,
CONSTRAINT pk_users_acc_psw PRIMARY KEY(account,password) #主键起别名无用 应为所有主键名字一定为PRIMARY
)

12.4 外键约束

外键的作用

限定某表字段的引用完整性

约束等级

  • Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录
  • Set null方式:在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null
  • No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
  • Restrict方式:同no action,都是立即检查外键约束
  • Set default方式(在可视化工具sQLyog中可能显示空白)︰父表有变更时,子表将外键列设置成一个默认的值,但lnnodb不能识别

如果没有指定等级,就相当于Restrict方式。
对于外键约束,最好是采用: ON UPDATE CASCADE ON DELETE RESTRICT的方式。

例如:

CREATE TABLE IF NOT EXISTS users1(
account int,
password int,
CONSTRAINT pk_users_acc_psw PRIMARY KEY(account,password) ON UPDATE CASCADE ON DELETE RESTRICT
)

是否应该使用外键 ?

不建议使用 需要用到外键约束的地方在应用 层处理

在MysQL里,外键约束是有成本的,需要消耗系统资源。对于大并发的sQL操作,有可能会不适合。比如大型网站的中央数据库,可能会因为外键约束的系统开销而变得非常慢。所以,MySQL允许你不使用系统自带的外键约束,在应用层面完成检查数据一致性的逻辑。也就是说,即使你不用外键约束,也要想办法通过应用层面的附加逻辑,来实现外键约束的功能,确保数据的一致性。

阿里开发规范

【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
说明:(概念解释)学生表中的student_id是主键,那么成绩表中的student_id则为外键。如果更新学生表中的student_id,同时触发成绩表中的student_id更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

12.5 检查约束

MySQL5.7不支持CHECK约束,MysQL8.0支持CHECK约束。

#8. check束
# MySQL5.7不支持CHECK约束,MysQL8.0支持CHECK约束。CREATETABLE test10(
id INT,
last _name VARCHAR( 15),
I
salary DECIMAL ( 10,2)CHECK (salary > 2000)

12.6 默认值约束

CREATETABLE test11(id INT,
last_name VARCHAR(15) ,
salary DECIMAL,( 10,2)DEFAULT2000)

13 视图

因为视图基于表,如果表结构改变则视图也需要改变,会增加维护成本

``所以,在创建视图的时候,你要结合实际项目需求,综合考虑视图的优点和不足,这样才能正确使用视图,使系统整体达到最优`

视图的应用场景:针对于小型项目,不推荐使用视图。针对于大型项目,可以考虑使用视图。

13.1 为什么使用视图

视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。比如,针对一个公司的销售人员,我们只想给他看部分数据,而某些特殊的数据,比如采购的价格则不会提供给他。再比如,人员薪酬是个敏感的字段,那么只给某个级别以上的人员开放,其他人的查询视图中则不提供这个字段。

13.2 视图的理解

  • 视图是一种虚拟表,本身是不具有数据的,占用很少的内存空间,是SQL中一个重要概念
  • 视图建立在已有表的基础上,视图赖以建立的这些表称为基表。
  • 查询视图就是查询基表的数据,修改视图也是修改基表的数据,反之亦然
  • 向视图提供数据内容的语句为SELECT语句,可以将视图理解为存储起来的SELECT语句

创建视图

#创建视图
CREATE VIEW v_test1
AS
SELECT name '姓名',salary '工资' #别名会是视图的字段名
FROM users

SELECT *
FROM v_test1

14 存储过程

14.1 理解存储过程

含义︰存储过程的英文是 Stored Procedure。它的思想很简单,就是一组经过预先编译的sQL语句的封装。执行过程:存储过程预先存储在MysQL服务器上,需要执行的时候,客户端只需要向服务器端发出调用存储过程的命令,服务器端就可以把预先存储好的这一系列sQL语句全部执行。

好处:

  1. 简化操作,提高了sql语句的重用性,减少了开发程序员的压力
  2. 减少操作过程中的失误,提高效率
  3. 减少网络传输量(客户端不需要把所有的sQL语句通过网络发给服务器)
  4. 减少了SQL语句暴露在网上的风险,也提高了数据查询的安全性

14.2 分类

存储过程的参数类型可以是IN、OUT和INOUT。根据这点分类如下:

  1. 没有参数(无参数无返回)

  2. 仅仅带IN类型(有参数无返回)

  3. 仅仅带oUT类型(无参数有返回)

  4. 既带IN又带oUT(有参数有返回)

  5. 带INOUT(有参数有返回)

    注意:IN、OUT、INOUT都可以在一个存储过程中带多个

14.3 需要设置新的结束标记(SQLyog 中必需 navicat可写可不写)

DELIMITER 新的结束标记
因为MysQL默认的语句结束符号为分号;。为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符

CREATE PROCEDURE select_users8(INOUT n VARCHAR(10))
BEGIN
	SELECT manager INTO n 
	FROM users
	WHERE name = n;
END

SET @n :='a';
CALL select_users2(@n);
SELECT @n

15 存储函数

CREATE FUNCTION f_test1(n VARCHAR(10))
RETURNS VARCHAR(10)
#函数特征
DETERMINISTIC   #同样的输入 输入结果是一致的
CONTAINS SQL    #有SQL语句
READS SQL DATA  #包含读数据的SQL

BEGIN
  RETURN (SELECT name FROM users WHERE name = n);
END

SELECT f_test1('a')

如果没有写函数特征则需要执行以下语句保证函数创建成功:

#创建函数前执行此语句,保证函数的创建会成功
SET GLOBAL log_bin_trust_function_creators = 1;

#创建函数前执行此语句,保证函数的创建会成功
SET GLOBAL log_bin_trust_function_creators = 1;
CREATE FUNCTION f_test2(n VARCHAR(10))
RETURNS VARCHAR(10)
BEGIN
	RETURN (SELECT name FROM users WHERE name = n);
END

16 变量

16.1 系统变量 (全局 、会话)

作为MysQL编码规范,MySQL中的系统变量以两个"@”开头,其中“@@global"仅用于标记全局系统变量,“@@session"仅用于标记会话系统变量。“@@""首先标记会话系统变量,如果会话系统变量不存在,则标记全局系统变量

16.2 用户变量(会话用户变量 、 局部变量)

用户变量以一个@开头

16.3 会话用户变量

会话用户变量:只要会话连接不断开,变量就一直存在

SET @a1 = 1;
SET @a2 = 2;
SET @sum =@a1+@a2;

SELECT @sum;
#-----------------------
SELECT salary INTO @s
FROM users
WHERE id = 1;

SELECT @s;

16.4 局部用户变量

  1. 使用DECLARE 声明
  2. 声明并使用在BEGIN … END中(使用在存储过程、函数中)
  3. DECLARE的方式声明的局部变量必须声明在BEGIN中的首行的位置。

注意

操作符

  1. Mysql不同于java ,‘+’号没有连接的意思,只代表加法运算,例如: 100 + “1” 在java中为1001,而在Mysql中为101 Mysql中一些特殊的运算100+‘a’ = 100 100+NULL = NULL
  2. Mysql字符串存在隐式转换 ,如果数值转换失败,则看作0
  3. Mysql不支持聚合函数嵌套
  4. 浮点数是不够精准的,二进制存储会导致精度丢失。需要精度高的地方建议使用DECIMAL
  5. = 和 :=只有在SET和UPDATE的时候作用一样,起赋值的作用(SET @a=1和SET @a:=1是一样的);除了SET和UPDATE时, =都表示等于(WHERE id = 1); :=在任何时候都表示赋值

猜你喜欢

转载自blog.csdn.net/qq_61672548/article/details/126694362
今日推荐