这是一个系列文章,完整列表在这里:

🚀 Java后端面试必备技能列表

Java Version:如果没有特别说明,那么默认Java8,hotspot虚拟机。

MySQL Version:如果没有特别说明那就是最后一个5.x版本5.7.44。


关系数据库特点

MySQL是典型的关系数据库(Relational Database Management System, RDBMS),它由多张SQL表组成。对于关系型数据库,主要有以下几个特点:

二维表结构

关系型数据库(database)的基本元素是数据表(table),他可以理解为一张二维表,由行(row)和列(column)组成。每一行就是一条记录,每一列就是一个字段,下面是一张标准sql表:
table

表结构固定

关系型数据库在创建后拥有固定的表结构,后续数据的插入需要符合已经设定的字段和数据类型。

使用SQL查询

关系型数据库使用结构化查询语言SQL对数据库操作,支持多种复杂的查询方式,入多表关联,事务等。

支持事务

事务的作用,就是为了确保数据的完整性和一致性,它规定了一组操作要么全部执行,要么全部不执行。关系型数据库一般都会支持事务ACID属性。即:

原子性(Atomicity

事务是一个不可分割的最小单元,一组事务操作要么全部执行,要么全部不执行。如果事务执行失败,它所作的操作会被回滚到操作前的状态。

一致性(Consistency

事务执行前后,必须使数据库从_一个一致状态_转换为_另一个一致状态_。比如你给我转账,转账前后我俩金额发生了变化,但是总金额必须还是相等的。

隔离性(Isolation

多个事务同时执行,每个事务执行结果不会互相影响。比如你给我转账的同时他也给我转账,那么我最终应该收到你俩的转账。

持久性(Durability

事务提交后,对数据库的改变将被永久的储存下来,即使系统故障,也能将已提交的数据恢复。

数据库三范式

数据库范式,是为了让数据库减少冗余和规范化,范式越高,对数据库的约束也就越多。当前数据库满足三范式已经很不错了,更高级别的范式(BC范式,第四,第五,第六范式),会让数据库之间的关系更加复杂,会增大获取数据的成本(高IO等)。

第一范式(1NF)

数据表中的每一列是原子性的,每个字段不可再分

第二范式(2NF)

满足第一范式的基础上,数据表要有主键,其他字段都依赖主键

地三范式(3NF)

满足第二范式的基础上,非主键字段,互相是独立无关

反范式

反范式是一种很烂的设计,虽然可以短期的获取一些便利,比如通过增加冗余表等方式降低join开销,减少IO,但是长久以往会使数据库的结构越发混乱,并不建议做过多反范式。

MySQL存储引擎

存储引擎是表的属性。以我现在使用的V5.7.22版本为例,通过命令查看MySQL数据库支持的执行引擎如下,可以看到默认的执行引擎是InnoDB:
mysql_engines
MySQL在之前的版本也使用过MYISAM作为默认存储引擎,后来就将执行引擎换成了INNODB。我认为这种替换,肯定是因为INNODB更加适合现代数据库需求,所以非必要请别使用MYISAM。

常见的MySQL存储引擎

InnoDB

特点:支持事务、行级锁定、外键约束、崩溃恢复。
用途:适用于需要高可靠性、事务处理和数据完整性的应用场景,如金融、订单处理等。
优点:事务支持、行级锁、崩溃恢复、外键约束。

MyISAM

特点:不支持事务,使用表级锁定,数据读取速度快,适合读多写少的应用。
用途:适用于读密集型应用,如数据仓库、报表生成等。
优点:占用空间小,读性能优异。

Memory

特点:数据存储在内存中,速度极快,但数据非持久化,重启后数据丢失。
用途:适用于需要高速数据访问且对数据持久性要求不高的场景,如临时数据存储、缓存等。
优点:读写速度极快。

MYISAM和INNODB多维度比较

维度 MyISAM InnoDB
事务支持 不支持事务 支持事务,遵循ACID原则
锁机制 表级锁定,读写操作都会锁定整个表 行级锁定,高并发下性能优越
外键支持 不支持 支持外键,确保数据参照完整性
全文索引 支持(较适合全文检索) MySQL 5.6及以上版本支持
数据存储 数据与索引分开存储,使用.MYD.MYI文件 数据与索引一起存储,使用.ibd文件
崩溃恢复 恢复速度较慢,数据可能丢失 自动崩溃恢复,数据一致性更好
表空间 每个表有独立的文件 所有表共享表空间,或者每个表独立表空间(可配置)
适用场景 读操作为主,不需要事务或外键支持的应用场景 高并发、频繁读写,需要事务和数据一致性的场景
存储文件大小 较小,由于没有事务日志,磁盘占用较少 较大,因为事务日志会占用更多磁盘空间
崩溃后的数据恢复 依赖于备份,可能导致数据丢失 自动崩溃恢复,通常不会丢失数据
数据行数限制 对数据行数没有限制,但受限于操作系统文件大小 支持非常大的数据表,受限于InnoDB表空间大小

MyISAM适用于读操作密集、需要全文检索、不需要事务支持的应用。
InnoDB更适合高并发、需要事务支持和数据完整性的应用。

MYISAM和INNODB索引比较

对于这两个存储引擎的比较,主要从以下两个方面比较:

聚簇索引 & 非聚簇索引

下面是聚簇索引和非聚簇索引的结构图:在聚簇索引中,红色的数字就是主键🆔,叶子节点上的data就是记录,data中有name,age,gender等字段。在非聚簇索引中,蓝色的数字是使用age字段构建的索引,在叶子节点上红色的数字是主键🆔。也就是说,非聚簇索引最终还是查询的主键索引。
index
聚簇索引:即主键索引,一级索引。非叶子节点存储索引(id),叶子节点存储数据(age)。
非聚簇索引:即二级索引。非叶子节点存储索引(age),叶子节点存储主键+索引(age+id)。

B-tree(B🌳)结构 & B+tree结构(B+🌳)

B树和B+树特点
1.自平衡结构:无论经过多少次插入和删除,由于页分裂和页合并,它可以使树的高度保持在一个相对小的范围,时间复杂度稳定在O(logn)
2.多路搜索树:树有多个分支,每个分支平均查询路径差不多,减少IO次数
3.节点有序性:节点中数据和索引有序排列,有效支持二分查找,方便范围查询。
4.多键值存储:每个节点可以存储多个键值,减少了树的高度,提高了查询和更新操作效率。

MYISAM默认使用B-tree存储索引,INNODB默认使用B+tree存储索引。
Btree
B-tree
他的结构是:非叶子节点和叶子节点都存储数据和索引。
他更适合那些需要频繁插入、删除且希望快速查找到数据的场景,因为数据可以存储在内部节点,减少了部分操作的深度。
B+Tree
他的结构是:非叶子节点只存储索引,叶子节点存储数据和索引,叶子节点之间有双向指针形成链表。
他是更常用的索引结构,特别是在数据库系统中。它在范围查询、有序访问、磁盘I/O优化方面有显著优势,适合于大规模数据集和需要稳定查询性能的场景。

一条sql的执行过程

下面这幅图,是我在processon上面搜到的,很好的说明了一条sql语句的执行过程:
image
根据上面的图,我们很清楚的知道一条sql执行过程中,是需要客户端和服务端配合完成的,从功能上我们将这个流程划分为三个大的模块:1️⃣客户端2️⃣service层3️⃣存储引擎层。下面就讲讲每个模块都负责sql执行哪些内容:

客户端

客户端发送请求

客户端与服务端建立链接(TCP),用户在客户端输入sql语句,发送到服务端。这里的客户端可以是mysql命令行,GUI工具,应用程序中sql语句等。

service层

连接器处理请求

sql语句发送到服务端后,首先由连接器处理客户端请求。连接器会校验客户端的身份,以及是否有权执行该sql。

查询缓存结果

如果开启了查询缓存,mysql会先看这条sql以前是否被执行且缓存了结果,如果有则直接从缓存中返回查询结果,如果没有则继续执行。

解析器

解析器会对sql进行词法分析语法分析,将SQL语句翻译成mysql内部能理解的结构,并校验其语法的正确性(由预处理器完成),最终生成语法树(解析树)。

查询优化器

查询优化器接收解析器生成的语法树,并对查询计划进行优化,比如使用哪种索引,全表扫描还是索引扫描,连接表的顺序等,最终生成执行计划

执行器

执行器按照执行计划执行SQL语句,通过API调用存储引擎,访问数据库、索引等。如果开启了查询缓存,则缓存查询结果,否则直接返回给客户端。

存储引擎层

存储引擎根据执行器请求对索引和数据进行查询和管理。不同存储引擎数据管理方式也不同。

总结

这一篇主要是总结了一些MySQL的基础和关系型数据库的特点,以及典型代表MySQL数据库的一些特性:索引结构,存储引擎,执行过程。下一篇准备写MySQL进阶知识🧀,因为下面的内容都会涉及到log相关的东西,所以放在一起写。