MySQL执行流程、行记录格式、数据日志、数据库三大范式

sql执行流程

MySQL 的架构共分为两层:上层的Server 层和下层的存储引擎层
Server 层主要负责建立连接、分析和执行 SQL。存储引擎层主要负责数据的存储和提取。

第一步:通过连接器进行连接

我们首先需要连接 MySQL 服务器,然后才能执行 SQL。因为 MySQL 是基于 TCP 协议进行传输的,所以连接的过程需要先经过 TCP 的三次握手。
查询缓存
如果 SQL 是查询语句,MySQL 就会先去缓存里查找缓存数据,查询缓存是以 key-value 形式保存在内存中的。
如果查询的语句命中查询缓存,那么就会直接返回 value 给客户端。如果查询的语句没有命中查询缓存中,那么就要往下继续执行,等执行完后,查询的结果就会被存入查询缓存中。
但其实对于更新比较频繁的表,查询缓存的命中率很低的,所以,MySQL 8.0 版本直接将查询缓存删掉了。

第二步:解析器解析 SQL

在正式执行 SQL 查询语句之前, MySQL 会先对 SQL 语句做解析,这个工作交由「解析器」来完成。
词法和语法分析。MySQL 会根据输入的字符串识别出表名,字段名这些关键字。然后检验我们输入的 SQL 语句语法是否正确,比如把 from 写成了 form,这时 MySQL 解析器就会报错。

第三步:执行SQL

SELECT 查询语句流程主要可以分为三个阶段:
1、预处理阶段;
检查 SQL 查询语句中的表或者字段是否存在;把 select* 中的 * 符号,扩展为表上的所有列;
2、优化阶段;
优化器主要负责确定 SQL 查询语句的执行方案,比如在表里面有多个索引的时候,优化器会基于查询成本的考虑,来决定选择使用哪个索引。
3、执行阶段;
根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端;
连接器— 解析器 — 执行器

行记录存储格式

InnoDB 提供了 4 种行格式,比较经典的是Compact格式。
在compact行格式下,一行记录分为两个部分:额外信息和真实数据。
额外信息
3 个部分:变长字段的长度列表、NULL 值列表、记录头信息
变长字段的长度列表主要是存储变长字段所占用的数据大小,然后读取的时候根据这个长度列表来读取对应的数据长度。
(如果表里没有变长字段,那行格式就不会有变长字段长度列表)
NULL 值列表:因为表中的某些列可能会存储 NULL 值,如果把这些 NULL 值都放到记录的真实数据中会比较浪费空间,所以 Compact 行格式把这些值为 NULL 的列存储到 NULL值列表中。(如果字段都是 NOT NULL,就不会有 NULL 值列表)
记录头信息:主要包含标识这条数据是否被删除、下一条记录的位置等等。
真实数据
记录真实数据部分除了我们定义的字段,最前面还有三个隐藏字段,分别为:row_id、trx_id、roll_pointer。
如果表里既没有指定主键,又没有唯一约束,那么 InnoDB 就会为记录添加 row_id 隐藏字段,占六个字节。
trx_id是事务id,表示这个数据是由哪个事务生成的,占6个字节。
roll_pointer,这条记录上一个版本的指针。roll_pointer 是必需的,占 7 个字节。

行溢出

MySQL 中磁盘和内存交互的基本单位是页,一个页的大小一般是 16KB,也就是 16384字节,而一个 varchar 类型的列最多可以存储 65532字节,一些大对象如 TEXT、BLOB 可能存储更多的数据,这时一个页可能就存不了一条记录。这个时候就会发生行溢出,多的数据就会存到另外的「溢出页」中。

日志

undo log 回滚日志:是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC多版本并发控制。
在每个事务的执行过程中,都记录下回滚时需要的信息到一个日志里,那么在事务执行中途发生了 MySQL 崩溃后,我们可以通过这个日志回滚到事务之前的数据。
redo log 重做日志:是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于断电等故障恢复;
redo log 主要做的事情就是记录页的修改,比如某个页面某个偏移量处修改了什么,每当执行一个事务就会产生这样的一条或者多条物理日志。
在事务提交时,会先把 redo log 持久化到磁盘。当系统崩溃 MySQL 重启后,可以根据 redo log 的内容,把所有数据恢复到最新的状态。
undo log 记录了此次事务「开始前」的数据状态,记录的是更新之前的值;
redo log 记录了此次事务「完成后」的数据状态,记录的是更新之后的值;
binlog 归档日志:是 Server 层生成的日志,主要用于数据备份和主从复制;
MySQL 在完成一条更新操作后,Server 层还会生成一条 binlog,等之后事务提交的时候,会将该事务执行过程中产生的所有 binlog 统一写 入 binlog 文件。
binlog 文件是记录了所有数据库表结构变更和表数据修改的日志,不会记录查询类的操作,比如 SELECT 和 SHOW 操作。

数据库三大范式

第一范式
所谓第一范式是指数据库表的每一列都不能再分,也就是某个属性不能有多个值。简而言之,第一范式就是无重复的列。比如某条记录里小明的课程字段有数学语文英语,那就应该分为三条记录。
第二范式
满足第二范式必须先满足第一范式,第二范式要求数据库表中的每行必须可以被唯一地区分。这个唯一区分的方法通常是给表加上一个存储唯一标识的列,其实也就是主键。简而言之,第二范式就是有主键,非主键字段依赖主键。
第三范式
满足第三范式必须先满足第二范式。第三范式要求一个在数据库表中不能包含其它表中的非主关键字。
部门表里有ID、name,ID是主键。
那么在员工表里,最多只能加入部门ID,而不能再加入部门名称等字段,否则就会有大量的数据冗余。


数据库的三大范式是一组设计原则,用于指导如何构建关系数据库以确保数据的一致性、减少数据冗余和提高数据完整性。这些范式分别是:

第一范式(1NF - First Normal Form):

要求数据库表的每一列都是不可分割的基本数据项,即表中的所有字段都应该只包含原子性的值,没有重复的列组。
确保每个记录都是唯一的,可以通过主键来标识。
第二范式(2NF - Second Normal Form):

在满足第一范式的基础上,要求数据库表中的每一列都与主键直接相关,而不是间接相关,即没有部分依赖。
这意味着如果一个表有复合主键,那么非主键字段只能依赖于整个主键,而不是主键的一部分。
第三范式(3NF - Third Normal Form):

在满足第二范式的基础上,要求非主键字段不能相互依赖,即没有传递依赖。
这意味着表中的非主键字段只能依赖于主键,而不能依赖于其他非主键字段。
除了这三大范式,还有一些其他的范式,如BCNF(Boyce-Codd Normal Form)和第四范式(4NF)和第五范式(5NF),它们进一步规范了数据库设计:

BCNF(Boyce-Codd Normal Form):

是第三范式的加强版,要求表中的每一行只依赖于一个候选键。
第四范式(4NF - Fourth Normal Form):

要求数据库表中不存在多值依赖,即一个表中不应该有两个或多个独立的多值事实关于同一个主键。
第五范式(5NF - Fifth Normal Form):

也称为完美范式(PJNF - Project-Join Normal Form),要求消除表中的所有连接和投影依赖。
遵循这些范式可以帮助数据库设计者创建出结构清晰、数据冗余最小化、易于维护和扩展的数据库。然而,在实际应用中,有时候为了性能或其他考虑,可能会有意地违反某些范式。因此,数据库设计是一个需要在范式遵循和实际需求之间取得平衡的过程。

  • 31
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值