MySQL体系结构
Mysql是一个单进程多线程架构的数据库,分为 连接层、服务层、存储引擎层和系统文件层。
连接池:存储和管理客户端与数据库的连接,一个线程负责管理一个连接并处理这个连接上的sql请求。
缓存:缓存把执行过的语句和结果集以key-value对的形式存储。如果查询能够命中,那么结果集被直接返回给客户端。
如果在缓存未命中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。
查询缓存往往弊大于利。因为查询缓存的失效非常频繁,对一个表的某一条数据更新,这个表上所有的查询缓存都会被清空。
解析器:词法分析(将SQL语句分词,分析关键字、操作对象、表和字段等) + 语法分析(判断SQL语句是否满足MySQL语法)。
优化器:主要针对表,如果存在多个多个索引的时候,决定使用哪个索引;多表关联(join)时,决定各个表的连接顺序 等;生成执行计划。
执行器:打开表,根据sql所在表的存储引擎调用该引擎提供的接口来执行前面生成的sql执行计划。
存储引擎:存储引擎有多种类型,存储引擎的作用是负责文件数据的存储,每种存储引擎提供了相同名称但具体实现不同的接口给用户层。不同类型引擎的存储机制、索引实现和锁功能不同,这是为了让用户适应多种应用场景的需求。
需要特别注意,存储引擎只基于表,而非数据库。
文件系统:属于操作系统层面,mysql应用层可以调用操作系统提供的系统调用操作文件,发起IO请求。
MySQL存储引擎
InnoDB:支持事务,行锁、外键、非锁定读(读数据不上锁)、使用多版本并发控制(MVCC)提高并发性、隔离级别为repeatable并使用next-key locking 策略避免幻读、采用聚集索引。
需要注意:聚集索引和非聚集索引关键不在于索引和数据记录是否放在一个文件,而在于数据记录是否按照主键的顺序存放。
MyISAM:不支持事务、使用表锁、采用非聚集索引、一个表由MYD(存放数据记录)和MYI(存放索引)两个文件组成(frm表结构文件除外)。
NDB:是一个集群存储引擎,数据全部放在内存中。
Memory:表数据全部存放于内存,适合用于存储临时数据的临时表、使用哈希索引、只支持表锁,并发性差、不支持TEXT 和 BLOB类型,存储varchar时按照char方式存储,比较浪费内存。
mysql使用memory存储引擎作为临时表存放查询的中间结果(如分组、排序等),如果中间结果集超过Memory表的容量设置或者中间结果含有TEXT或BLOB类型字段,则会将中间结果转为MyISAM表存在磁盘中导致查询性能更慢。
Archive:其目标是提供高速插入和压缩存储功能、只支持insert和select操作、使用zlib对数据行压缩后存储、适用于存储归档数据如日志、使用行锁,但本身不是事务安全的。
Federated:本身不存放数据,而是指向远程mysql服务的一个表,实现对该表的操作。
Maria:开发时目的是用于替代MyISAM成为默认引擎的,提供和InnoDB基本一样的功能。
比对InnoDB和MyISAM
· 事务和外键
InnoDb支持事务和外键,一致性需求有保障。MyISAM不支持事务。
· 锁机制
InnoDb支持行级锁,基于索引加锁实现行级锁。
MyISAM支持表级锁,锁定整张表。
· 索引结构
InnoDB使用聚集索引,而且索引和记录一起存储。
MyISAM使用非聚集索引,索引和记录分开存。
· 并发处理能力
MyISAM使用表锁,任何一个写操作都会锁住整个表,所以一张表中任何两个记录的修改无法并发进行,只能串行。读写和写写串行,读读可并发,粒度为表。
InnoDB使用行锁,并且使用MVCC优化了读写并发,因此读读,读写可并发,写写串行,粒度为行。
· 存储文件
InnoDB表对应两个文件:.frm表结构、.ibd数据文件。
MyISAM表对应3个文件:.frm表结构、.MYD数据文件、.MYI索引文件。
· 使用场景
MyISAM适合不需要事务支持(一致性要求不高)、并发需求低、数据修改较少(因为写写是串行的,所以写操作性能低)以读为主的场景。
InnoDB则相反。