Java后端必备技能(三):MySQL基础篇
这是一个系列文章,完整列表在这里:
Java Version:如果没有特别说明,那么默认Java8,hotspot虚拟机。
MySQL Version:如果没有特别说明那就是最后一个5.x版本5.7.44。
关系数据库特点
MySQL是典型的关系数据库(Relational Database Management System, RDBMS),它由多张SQL表组成。对于关系型数据库,主要有以下几个特点:
二维表结构
关系型数据库(database)的基本元素是数据表(table),他可以理解为一张二维表,由行(row)和列(column)组成。每一行就是一条记录,每一列就是一个字段,下面是一张标准sql表:
表结构固定
关系型数据库在创建后拥有固定的表结构,后续数据的插入需要符合已经设定的字段和数据类型。
使用SQL查询
关系型数据库使用结构化查询语言SQL对数据库操作,支持多种复杂的查询方式,入多表关联,事务等。
支持事务
事务的作用,就是为了确保数据的完整性和一致性,它规定了一组操作要么全部执行,要么全部不执行。关系型数据库一般都会支持事务ACID属性。即:
原子性(Atomicity)
事务是一个不可分割的最小单元,一组事务操作要么全部执行,要么全部不执行。如果事务执行失败,它所作的操作会被回滚到操作前的状态。
一致性(Consistency)
事务执行前后,必须使数据库从_一个一致状态_转换为_另一个一致状态_。比如你给我转账,转账前后我俩金额发生了变化,但是总金额必须还是相等的。
隔离性(Isolation)
多个事务同时执行,每个事务执行结果不会互相影响。比如你给我转账的同时他也给我转账,那么我最终应该收到你俩的转账。
持久性(Durability)
事务提交后,对数据库的改变将被永久的储存下来,即使系统故障,也能将已提交的数据恢复。
数据库三范式
数据库范式,是为了让数据库减少冗余和规范化,范式越高,对数据库的约束也就越多。当前数据库满足三范式已经很不错了,更高级别的范式(BC范式,第四,第五,第六范式),会让数据库之间的关系更加复杂,会增大获取数据的成本(高IO等)。
第一范式(1NF)
数据表中的每一列是原子性的,每个字段不可再分
第二范式(2NF)
满足第一范式的基础上,数据表要有主键,其他字段都依赖主键
地三范式(3NF)
满足第二范式的基础上,非主键字段,互相是独立无关
反范式
反范式是一种很烂的设计,虽然可以短期的获取一些便利,比如通过增加冗余表等方式降低join开销,减少IO,但是长久以往会使数据库的结构越发混乱,并不建议做过多反范式。
MySQL存储引擎
存储引擎是表的属性。以我现在使用的V5.7.22版本为例,通过命令查看MySQL数据库支持的执行引擎如下,可以看到默认的执行引擎是InnoDB:
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字段构建的索引,在叶子节点上红色的数字是主键🆔。也就是说,非聚簇索引最终还是查询的主键索引。
聚簇索引:即主键索引,一级索引。非叶子节点存储索引(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存储索引。
B-tree
他的结构是:非叶子节点和叶子节点都存储数据和索引。
他更适合那些需要频繁插入、删除且希望快速查找到数据的场景,因为数据可以存储在内部节点,减少了部分操作的深度。
B+Tree
他的结构是:非叶子节点只存储索引,叶子节点存储数据和索引,叶子节点之间有双向指针形成链表。
他是更常用的索引结构,特别是在数据库系统中。它在范围查询、有序访问、磁盘I/O优化方面有显著优势,适合于大规模数据集和需要稳定查询性能的场景。
一条sql的执行过程
下面这幅图,是我在processon上面搜到的,很好的说明了一条sql语句的执行过程:
根据上面的图,我们很清楚的知道一条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相关的东西,所以放在一起写。