mysql架构与存储引擎 (Myisam与Inoodb)

mysql抽象架构:可以分为SQL LayerStorage Engine Layer

mysql的engine层是基于表的,不是基于库的,创建表的语句可以指定engine

SQL Layer:

初始化模块:mysqlserver启动时,初始化模块会加载默认参数,分配buffer多大内存,cache多大等等

连接管理模块:mysql当有请求进来时,通过连接管理模块接受请求并转发到连接进程模块(可以理解为线程池,有连接到了,检查线程池中是否有活跃的线程,如果有,这个线程服务这个连接,没有的话创建一个新的连接进行服务)

然后到用户模块检查连接是否有权限访问,然后再到命令分发器,首先到查询缓存模块检查是否有缓存,如果有缓存则到日志记录模块记录日志直接返回,否则到日志记录模块记录日志再到命令解析器,进行解析不同的请求分发到不同模块。

核心API类似于java中JVM,管理数据库

查询缓存模块:mysql自带cache,类似于map,key:sql语句 value:查询结果。cache是基于查询的cache  当有增删改查时cache会失效,当对mysql优化时可以将cache调大点。

1)mysql启动以后,初始化模块就从系统配置文件中读取系统参数和命令参数,初始化整个系统,同时存储引擎也会启动;

2)初始化结束后,连接管理模块会监听客户端的连接请求,并将连接请求转发给连接进程模块去请求一个连接线程;

3)连接进程模块接到请求后会调用用户模块进行授权检查,通过授权以后会检查是否又空闲线程,如果有取出并与客户端连接,如果没有则新建立建立一个线程与客户端连接;

4)mysql请求分为两种,一种是需要命令解析和分发才能执行(query请求,需要调用 Parser解析器 也就是Query 解析和转发模块的解析才能够执行的请求),另一种可以直接执行(command请求不需要调用 Parser 就可执行);不管哪种,如果开启了日志,那么日志模块会记录日志;

5)如果是Query类型的请求,会将控制权交给Query解析器,Query解析器检查是否Select类型,如果是则启动查询缓存模块,如果缓存命中则将缓存数据返回给连接进程模块,连接线程将数据传递到客户端;如果没有缓存或者不是一个可以缓存的查询,此时解析器会进行相应的处理,通过查询分发器给相关的处理模块;

6)如果解析器结果是DML/DDL,则交给变更模块;如果是检查、修复的查询交给表维护模块,如果是一条没有被缓存的语句,则交给查询优化器模块。实际上表变更模块又分为若干小模块,例如:insert处理器、delete处理器、update处理器、create处理器,以及alter处理器这些小模块来负责不同的DML和DDL。总之,查询优化器、表变更模块、表维护模块、复制模块、状态模块都是根据命令解析器的结果不同而分发给不同的类型模块,最后和存储引擎进行交互。

7)当一条命令执行完毕后,控制权都会还给连接线程模块,在上面各个模块处理过程中都依赖于核心API模块,比如:内存管理、文件I/O,字符串处理等。

Storage Engine Layer:

Innodb与Myisam,不管是关系型数据库(rdbms)还是nosql,数据都存储在文件中。mysql数据存储在data下,一个数据库对应一个文件夹。

Innodb与Myisam的区别:

1.

1.存储结构 

Innodb有两个存储文件,.frm表定义文件与.ibd数据文件  其中ibd文件中存储了数据与索引信息,而Myisam中则使用了三个文件,将数据与索引分开存储

2.表锁差异

MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的

3、事务

Innodb支持事务原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability) Myisam强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持

4.CRUD操作

MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。

5.count操作

当count(*)时,Inoodb需要进行扫表查询数量,消耗非常大。

而Myisam中存储了count信息可以直接取出该值。

如果加了where条件,这两个索引处理方式就一样了。

6.索引结构都是B+Tree

衡量一个索引好不好的关键是IO渐进复杂度,B+Tree树的高度是可控的,可以降低IO渐进复杂度。

7. 外键

MyISAM:不支持
InnoDB:支持

8、 表主键

MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。

9、 全文索引

MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。

总结:

InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,InnoDB的表现肯定要比MyISAM强很多。但是,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。

B+Tree与B Tree的区别:

B-Tree的key和data是一起的,B+Tree做了改进将data都放在了叶子节点,所有的中间节点都是key

关于B+Tree有一篇非常优质的博客可以看下 http://blog.codinglabs.org/articles/theory-of-mysql-index.html

Inoodb与Myisam下的索引存储图:

Mysiam中主索引和副索引的叶子节点都指向数据文件中的地址。

Inoodb中数据是附在叶子节点上的,查询主索引会直接定位到叶子节点的数据。而查询副索引会进行两次查询,先查询到副索引叶子节点对应的主索引值,在通过主索引查询数据。select * from table where id = (select id from table where name="mic")

猜你喜欢

转载自blog.csdn.net/qq_37113604/article/details/88831254