基础知识:

服务器处理客户端请求:

1.原理:

客户端进程向服务器进程发送一段文本 ( MySQL 语句) .服务器进程处理后再向客户端进程返回一段文本(处理结果)。
image.png

2.连接管理:

1.每当有一个客户端进程连接到服务器进程时,服务器进程都会创建一个线程,专门处理与这个客户端的交互; 当该客户端退出时会与服务器断开连接, 服务器并不会立即把与该,客户端交互的线程销毁, 而是把它缓存起来, 在另一个新的客户端再进行连接时,把这个缓存的线程分配给该新客户端.这样就不用频繁地创建和销毁线程,从而节省了开销.
2.在客户端程序发起连接时, 需要携带主机信息、用户名、密码等信息,服务器程序会对客户端程序提供的这些信息进行认证.如果认证失败, 服务辑程序会拒绝连接.另外,如果客户端程序和服务器程序不运行在一台计算机上,我们还可以通过采用传输层安全性 (TransportLayer Security , TLS) 协议对连接进行加密,从而保证数据传输的安全性。当连接建立后,与该客户端关联的服务器线程会一直等待客户端发送过来的请求.MySQL 服务器接收到的请求只是一个文本消息,该文本消息还要经过各种处理.

1
1.客户端发起连接需携带一些认证信息,认证成功就在服务段创建线程,然后该线程一直监听客户端发送来的请求。客户端断开连接后该线程并不会销毁而是缓存起来

解析与优化:

1
2
3
4
5
1.MySQL 服务器程序处理查询请求的过程是这样,会把刚刚处理过的查询请求和结果缓 存起来.  如果下一次有同样的请求过来,直接从缓存中查找结果就好了,就不用再去底层的表中查找了. 这个查询缓存可以在不同的客户端之间共享,也就是说,如果客户端 A 刚刚发送 了 一个查询请求,而客户端 B 之后发送了同样的查询请求,那么客户端 B 的这次查询就可以直接使用查询缓存中的数据了.
注:如果两个查询请求有任何字符上的不同(例如,空格、注释、大小写),都会导致缓存不会命中。另外,如果查询请求中包含某些系统函数、用户自定义变量和函数、系统表,则这个请求就不会被缓存.
2.当查询的表数据结构失效后缓存也就失效了。
注:MySQL8.0中直接将缓存删除
3.

语法解析:

1
1.如果查询缓存没有命中,接下来就需要进入正式的查询阶段了。因为客户端程序发送过来的请求只是一段文本,所以MySQL服务器程序首先要对这段文本进行分析,判断请求的语法是否正确,然后从文本中将要查询的表、各种查询条件都提取出来放到MySQL服务器内部使用的一些数据结构上。

查询优化:

1
1.在语法解析之后,服务器程序获得到了需要的信息,比如要查询的表和列是哪些、搜索条件是什么等.但光有这些是不够的,因为我们写的 MySQL 语句执行起来效率可能并不是很高, MySQL 的优化程序会对我们的话句做一些优化。

存储引擎:

1
2
3
4
5
6
7
1.到服务器程序完成了查询优化为止,还没有真正地去访问真实的表中数据
2.MySQL 服务器把数据的存储和提取操作都封装到了一个名为存储引擎的模块中.我们知道,表是由一行一行
的记录组成的,但这只是一个逻辑上的概念.在物理上如何表示记录,怎么从表中读取数据,以及怎么把数据写入具体的物理存储器上,都是存储引擎负责的事情.为了实现不同的功能,MySQL 提供了各式各样的存储引擎,不同存储引擎管理的表可能有不同的存储结构, 采用的存取算法也可能不同.
3.为了方便管理,人们把 MySQL 服务器处理请求的过程简单地划分为 server 层和存储引擎层.连接管理、查询缓存、语法解析、查询优化这些并不涉及真实数据存取的功能划分为 server 层的功能,存取真实数据的功能划分为存储引擎层的功能.各种不同的存储引擎为server 层提供统一的调用接口,其中包含了几十个不同用途的底层函数,比如"读取索引第一条记录读取索引下一条记录" "插入记录"等.
4.所以在 server 层完成了查询优化后,只需按照生成的执行计划调用底层存储引擎提供的接口获取到数据后返回给客户端就好了
5.server 层和存储引擎层交互时,一般是以记录为单位的.以 SELECT 语句为例, se凹er 层根据执行计划先向存储引擎层取一条记录,然后判断是否符合 WHE阻条件:如果符合, 就发送给客户端,否则跳过该记录,
然后继续向存储引擎索要下一条记录:依此类推.
1
2
3
4
5
6
7
8
9
10
11
12
13
6.存储引擎的常见操作:
1.查看当前服务器程序支持的存储引擎:
show engines ;
2.设置表的存储引擎:
创建表时指定存储引擎:
CREATE TABLE 表名(
建表语句,
) ENGINE =存储引擎名称;
修改表的存储引擎:
ALTER TABLE 表名 ENGINE =存储引擎名称;
3.查看存储引擎:
show create table 表名 ;
4.

系统变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1.查看系统变量:
SHOW VARIABLES [LIKE 匹配模式];
2.设置系统变量:
通过启动选项设置:
1.通过命令行添加启动选项.
比方说在启动服务器程序时用这个命令:
mysqld --default-storage-engine-MyISAH --max-connections-10
2.通过配置文件添加启动选项.
可以这样填写配置文件
[server]
default-storage-engine- MyISAM
max-connections-10
3.服务器程序运行过程中设置:
• GLOBAL (全局范围): 影响服务器的整体操作.具有 GLOBAL 作用范围的系统变量
可以称为全面变量.
• session(会话范围),影响某个客户端连接的操作.具有 SESSION 作用范围的系统
变量可以称为会话变量.
•通过启动选项设置的系统变量的作用范围都是 GLOBAL 的;
•设置系统变量的语法:
SET (GLOBAL|SESSION) 系统变量名=值;
或者
SET [(@@(GLOBAL|SESSION).] 系统变量名=值;
•全局变量(global variables):
全局变量在MySQL服务器的整个生命周期内保持持久性,并且对所有会话都是可见的。这些变量可以被任何连接到MySQL服务器的客户端修改,并且对所有连接都具有相同的值。全局变量的值在MySQL服务器重启后仍然保持不变。
•会话变量(session variables):
会话变量是与特定会话相关联的变量。每个连接到MySQL服务器的客户端都会有自己的会话变量。这些变量的值只在当前会话中有效,并且对其他会话不可见。当会话结束时,会话变量的值将被清除。
•查看全局变量的值:
SHOW GLOBAL VARIABLES LIKE 'variable_name';
•查看会话变量的值:
SHOW SESSION VARIABLES LIKE 'variable_name';
•一些变量既可以作为全局变量又可以作为会话变量存在。在这种情况下,如果设置了会话变量的值,则会话变量的值将覆盖全局变量的值。如果没有设置会话变量的值,则会话变量将采用全局变量的值。
•SET 系统变量名=值"和 "SET SESSrON 系统变量名=值"是等价的.
•如果某个客户 端改变了 某个系统变量在 GLOBAL 作用范围的值,其并不会影响谅系
统变量在当前已经连接的客户端作用范围为 SESSION 的值,只会影响后续追入的客户
端作用范围为 SESSION 的值.
•并不是所有的系统变量都具有 GLOBAL 和 SESSION 的作用范围.

状态变量:

1
2
3
4
5
1.概念:为了让我们更好地了解服务器程序的运行情况,MySQL 服务器程序中维护了好多关于程序运行状态的变量,它们被称为状态变量.
2.由于状态变量是用来显示服务器程序运行状态的,所以它们的值只能由服务器程序自己来设置,不能入为设置.与系统变量类似,状态变量也有 GLOBAL 和 SESSION 两个作用范围,
查看'状态变量的语句可以这么写:
SHOW (GLOBAL|SESSION) STATUS (LIKE 匹配的模式);

字符集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在MySQL中,字符集(character set)定义了如何存储和处理文本数据的字符编码方式,而字符集比较规则(collation)则定义了如何对字符进行排序和比较。
字符集比较规则决定了在排序、字符串比较和索引等操作中字符的顺序和比较规则。不同的字符集比较规则可能会导致不同的排序结果和比较行为。
以下是一些常见的字符集比较规则:
utf8_general_ci:UTF-8编码的不区分大小写的比较规则,适用于一般的文本排序和比较。
utf8_bin:UTF-8编码的区分大小写的比较规则,区分大小写的排序和比较。
utf8mb4_general_ci:UTF-8编码的不区分大小写的比较规则,适用于包括Emoji在内的所有Unicode字符的排序和比较。
utf8mb4_bin:UTF-8编码的区分大小写的比较规则,区分大小写的排序和比较,适用于包括Emoji在内的所有Unicode字符。
在创建数据库、表或列时,可以指定字符集和字符集比较规则。例如:
CREATE DATABASE database_name CHARACTER SET charset_name COLLATE collation_name;
CREATE TABLE table_name (...) CHARACTER SET charset_name COLLATE collation_name;
ALTER TABLE table_name MODIFY column_name column_type CHARACTER SET charset_name COLLATE collation_name;
要查看数据库、表或列的字符集和字符集比较规则设置,可以使用以下语句:
SHOW CREATE DATABASE database_name;
SHOW CREATE TABLE table_name;
SHOW FULL COLUMNS FROM table_name;
在进行字符串比较、排序和索引时,确保选择正确的字符集和字符集比较规则非常重要,以避免不一致的排序结果和比较行为。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
字符集指的是某个字符范围的编码规则.
比较规则是对某个字符集中的字符比较大小的一种规则.
在 MySQL 中, 一个字符集可以有若干种比较规则,其中有一个默认的比较规则.一个比较规则必须对应一个字符集.
在 MySQL 中查看支持的字符集和比较规则的语句如下:
• SHOW (CHARACTER SET|CHARSET) [LIKE 匹配的模式);
• SHOW COLLATION [LIKE 匹配的模式);
MySQL 有 4 个级别的字符集和比较规则,具体如下.
· 服务器级别
character_set_server 表示服务器级别的字符集,
collation_server 表示服务器级别的比较规则.
数据库级别
创建和修改数据库时可以指定字符集和比较规则:
CREATE DATABASE 数据库名
[[DEFAULT] CHARACTER SET 宇符集名称]
[[DEFAULT] COLLATE 比较规则名称];
ALTER DATABA$E 数据库名
[[DEFAULT] CHARACTER SET 宇符集名称]
[[DEFAULT] COLLATE 比较规则名称];
character_set_database 表示当前数据库的字符集.
collation_database 表示当前数据库的比较规则.这两个系统交量只用来读取,修改它们并不会改变当前数据库的字符集和比较规则.如果没有指定当前数据库,则这两个系统变量与服务器级别相应的系统变量具有相同的值.
表级别
创建和修改袤的时候指定袤的字符集和比较规则:
CREATE TABLE 表名 (列信息)
[[DEFAULT] CHARACTER SET 宇符集名称]
[[DEFAULT] COLLATE 比较规则名称];
ALTER TABLE 表名
[[DEFAULT] CHARACTER SET 宇符集名称]
[[DEFAULT] COLLATE 比较规则名称];
列级别:
创建和修改列的时候指定该列的字符集和比较规则:
CREATE TABLE 表名(
列名 列类型 [CHARACTER SET 宇符集名称]
[[DEFAULT] COLLATE 比枝规则名称].
其他列...);

image.png
image.png

InnoDB记录存储结构:

1
2
1.读取数据和刷新数据lnnoDB 采取的方式是,将数据划分分为若干个页,以页作为磁盘和内存之间交互的基本单位.lnnoDB 中 页的大小一般为16KB。也就是在一般情况下,一次最少从磁盘中读取 16KB 的内容到内存中,一次最少把内存中的16KB 内容刷新到磁盘中。可以通过下面的命令查看Innodb页的大小:
SHOW VARIABLES LIKE 'innodb_page_size';

InnoDB 行格式:

1
2
3
1.我们平时都是以记录为单位向表中插入数据的,这些记录在磁盘上的存放形式也被称为行
格式或者记录格式.设计 InnoDB 存储引擎的大叔到现在为止设计了 4 种不同类型的行格式,
分别是 COMPACT、 REDUNDANT、 DYNAMIC 和 COMPRESSED.

指定行格式的语法:
image.png
COMPACT 行格式:
image.png
image.png
为了确定每个列的变长字段的长度用几字节表示:Innodb有一套规则。为了更好地表述清楚这个规则,我们引入 W、 M 和 L 这几个符号,先分别看看这些符号的意思.
image.png
image.png
image.png
image.png
127的二进制刚好是1111111,而int是8位,其第一位被用作标志为使用的一个字节还是2个字节来表示其变成列的长度。
另外需要注意的一点是,变*字段长度列表中只存储值为非NULL 的列的内容长度,不存储值为 NULL 的列的内容长度。
并不是所有记录都有这个变长字段长度列表的部分,如果表中所有的列都不是变长的数据类型或者所有列的值都是NULL 的话,就不需要有变长字段长度列表.
image.png
image.png
image.png
image.png
除了我们自己定义的列的数据外. MySQL会为每个记录默认地添加一些列(也称为隐藏列):
image.png
image.png
CHAR(M) 列的存储格式:
image.png
mysql学习-Innodb行格式compact行记录解析_compact行格式为什么存储长度时要逆序-CSDN博客

InnoDB 数据页结构:

数据页结构:

image.png
image.png

记录在页中的存储:

image.png

记录头信息:

1
2
1.deleted _ flag :这个属性用来标记当前记录是否被删除,占用1比特.值为 0 时表示记录没有被删除,值为 1 时表示记录被删除了.
这些被删除的记录之所以不从磁盘上移除,是因为在移除它们之后,还需要在磁盘上亟新排列其他的记录, 这会带来性能消耗,所以只打一个删除标记就可以避免这个问题.所有被删除掉的记录会组成一个垃圾链衰,记录在这个链表中占用的空间称为可重用空间(关于链表是怎么形成的,在介绍过 next_record 属性后大家就知道了).

image.png
image.png
image.png
image.png
image.png

Page Directory ( 页 目 录 ):

image.png
image.pngimage.png

Page Header (页面头部):

image.png
image.png
image.png
image.png
image.png
image.png

索引:

image.png
image.png
image.png

聚簇索引:

image.pngimage.png
image.png

二级索引:

就是根据非主键的列生成一个新的b+树,而这个树和聚簇索引树是类似的。只不过叶子节点不是完整的用户记录,而是该列和主键。然后根据找到的主键回表到聚簇索引中来查找完整的用户记录。这样的目的是节约了空间和时间。
image.png
image.png

联合索引:

就是以多个列来创建一种类似于二级索引的B+树
image.png

B+树索引的使用:

image.png
MySQL中键(key)和索引(index)的区别_key和index的区别-CSDN博客

使用索引:

image.png
image.png

MySQL的数据目录:

image.png

1
2
查看数据目录:
show variables like 'datadir'

image.png
image.png
InnoDB 和 MyISAM 这两种存储引擎都在数据目录下对应的数据库子目录中创建了一个专门用于描述表结构的文件, 文件名是下面这样:表名.frm;
image.png
系统表空间:这个系统表空间可以对应文件系统上一个或多个实际的文件.在默认情况下. lnnoDB 会
在数据目录下创建一个名为 ibdata 1 (在你的数据目录下找找看有没有)、大小为 12MB 的文件,这个文件就是对应的系统表空间在文件系统上的表示。
image.png
独立表空间:image.png
image.png
image.png
image.png
image.png

InnoDB 的表空间:

image.png
image.png
image.png
单表访问方法:

1
2
1、const:通过主键和二级索引来查找;
2.ref:设计 MySQL 的大叔把这种"搜索条件为二级索引列与常数进行得值比较,形成的扫描区间为单点扫描区间, 采用二级索引来执行查询"的访问方法称为 ref

image.png
image.png
ref和const之间关于二级索引的区别:const表示二级索引的列是唯一的,不重复的;而ref不是这样的
image.png
image.png
image.png
image.png

事务:

事务具有原子性,隔离性,一致性,持久性。
image.png
image.png
image.png
只有当事务处于提交的或者中止的状态时个事务的生命周期才算是结束了.对于已经提交的事务来说, 该事务对数据库所做的修改将永久生效; 对于处于中止状态的事务来说,该事务对数据库所傲的所有修改都会被回滚雪j没执行该事务之前的状态.
image.png
image.png
image.png
image.png
Snipaste_2024-01-09_13-37-53.pngimage.pngimage.png
image.png
image.png
image.png

事务日志:

尚硅谷mysql日志
https://www.cxyxiaowu.com/10740.html

事务隔离级别和MVCC:

事务一致性问题:

1
2
3
4
5
6
7
8
9
在事务中的语句在执行时,并不会立即对数据库进行实际的修改。事务中的语句在执行过程中,会生成对数据库的操作日志,而不是直接修改数据库的实际数据。
当调用事务的提交操作(COMMIT)时,事务将会执行以下步骤:
首先,数据库管理系统将会将事务所做的操作日志持久化到磁盘,即将操作日志写入事务日志
(Transaction Log)。
然后,数据库管理系统会将事务中的所有修改操作应用到数据库的实际数据中,将事务所做的修改更新到相关的数据页或索引中。
最后,数据库管理系统会通知应用程序事务已经成功提交,并将事务从活动状态转换为已完成状态。
这样,通过事务的提交,数据库实际上才会将事务中的修改操作应用到数据库中,使其对其他事务可见。
如果在事务执行过程中发生了错误或者执行了回滚操作(ROLLBACK),那么事务中的语句所做的修改操作将不会被提交。数据库管理系统会将事务操作日志中的记录进行撤销,从而回滚事务的修改,恢复到事务开始前的状态。
重要的是要理解,事务的提交是一个关键步骤,它标志着事务的最终确认和永久性的修改。在事务提交之前,事务所做的修改只存在于事务日志中,并不对其他事务可见。只有在提交时,数据库才会将这些修改应用到实际数据中。
1
2
3
4
5
6
7
8
9
事务(Transaction)是对数据库的一组操作作为一个逻辑单元进行执行的过程。事务具有原子性、一致性、隔离性和持久性(ACID)的特性。它将一系列操作(读取、写入、修改等)组合在一起,要么全部成功执行,要么全部回滚。
操作日志(Transaction Log)是数据库管理系统用于记录事务操作的一种机制。它是一个持久化的数据结构,用于记录每个事务的操作细节和顺序。操作日志通常以一种顺序的方式记录事务的开始、操作和结束。
操作日志的主要作用是提供数据的恢复和持久性。通过记录事务操作的详细日志,数据库可以在系统故障或崩溃后进行恢复,并确保数据的一致性和完整性。
在事务执行过程中,数据库管理系统将事务的操作记录写入操作日志,而不是直接修改数据库中的实际数据。这意味着在事务提交之前,数据库中的实际数据并没有发生变化,而是将相应的修改操作记录到操作日志中。
操作日志记录了事务执行的详细信息,包括事务的标识符、开始时间、操作类型(读取、写入、修改等)以及相应的数据内容。通过操作日志,数据库可以实现以下功能:
事务恢复:在系统故障或崩溃后,数据库可以通过回放操作日志来恢复未提交的事务或撤销已提交的事务,从而保证数据的一致性。
并发控制:操作日志可以用于实现并发控制机制,如多版本并发控制(MVCC)。数据库可以根据事务的开始时间和操作日志的顺序来确定事务的可见性和隔离性。
归档和备份:操作日志可以用于数据库的归档和备份。通过定期备份操作日志,可以在需要时还原数据库到特定时间点的状态。
在数据库系统中,操作日志是非常重要的组成部分,它确保了数据的可靠性和一致性。通过记录事务的操作细节,操作日志提供了数据恢复、并发控制和备份等关键功能。

1.事务开启后,其书写的sql语句,其实都会执行的,只不过提交是将其事务更改的数据刷新到磁盘中。
脏写:如果一个事务修改了另一个未提交事务修改过的数据, 就意味着发生了脏写现象。
脏读:如果一个事务读到了另一个未提交事务修改过的数据,就意味着发生了脏读现象。
不可重复读 ( Non-Repea~ble Read ) :如果一个事务修改了另一个半提交事务读取的数据, 就意味着发生了不可重复读现象,或者叫模糊读 ( Fu町 Read) 现象。
幻读 (Phantom):如果一个事务先根据某些搜索条件查询出一些记录,在该事务未提交时,另一个事务写
入一些了符合那些搜索条件的记录(这里的写入可以指 INSERT、DELETE、 UPDATE 操作) , 就意味着发生了幻读现象.

锁:

image.png
image.png
image.png
image.png
image.png
image.png
image.png
Snipaste_2024-01-09_14-47-54.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
InnoDB 中的行级锁:
image.png
image.png