MySQL之存储引擎
MySQL由于其开源扩展方便等诸多优点成为互联网公司首选的数据库。本文介绍一下MySQL的存储引擎,那么数据库和存储引擎是什么关系?这要先从MySQL的架构开始讲起。
MySQL架构
MySQL在逻辑上主要可以分为5层,从上到下分别是 “连接器”-->“查询缓存”-->“解析器”-->“优化器”-->“存储引擎”。
连接器模块主要负责客户端的连接处理,安全认证等。
查询缓存模块是MySQL的优化模块,当遇到条件相同的查询可以直接存该层获取,不用查询底层引擎。
解析器模块负责解析sql语法。
优化器模块会对解析器解析出来的语句进行分析优化,包括重写查询,决定表的读取顺序,选择索引等。
位于最后一层的存储引擎模块则是真正存储数据的地方。
常用存储引擎简介
MySQL的存储引擎有很多种,每种存储引擎都有不同的行为,这里我们主要介绍几个常用的引擎。
1.InnoDB:
InnoDB是最为常用的存储引擎,我们日常开发中数据库的大多数表都是基于InnoDB引擎,我们从以下几个方面介绍一下它
1.事务级别,它实现了标准事务,由于平时锁做开发大都有事务的要求,所以具备事务特性是必须的,InnoDB是MySQL的默认事务引擎,他被设计来处理大量的短事务,实现了标准的行级锁定。它采用MVCC
MVCC:多版本并发控制,通过在每行记录的后面加上两个事务版本号来实现,一个保存行的创建版本号,一个保存过期版本号,对于可重复读级别,select时只查找早于当前事务版本的记录,insert时为插入记录保存当前版本号,delete时同样保存当前版本号作为删除标识,update时保存当前版本号作为行版本号,并把当前版本号作用到原来的记录作为删除标识。使用mvcc可以使大多数操作不用加锁,但是mvcc需要额外存储空间以及维护工作,并且他只在读已提交和可重复读级别下工作
来支持高并发,默认的事务隔离级别是可重复读,并通过间隙锁防止幻读
隔离级别:涉及数据库的隔离级别以及各级别的问题,我们来复习一下,隔离级别由低到高分别是,读未提交级别:可以读取其他事务未提交的数据,这种现象称为脏读;读已提交:一个事务的两个相同查询因为其他事务的修改可能返回不同的结果,这种现象称为不可重复读;可重复读级别:某个事务在查询某一范围的记录时由于其他的事务在该范围内插入了新的记录,之前的事务再次读取时会产生幻行,称为幻读;串行化级别:事务的最高级别,强制事务串行执行,可以解决上面各个级别的缺陷,但是并发性能较差。
间隙锁不仅会锁定查询到的行,还会对索引中的间隙进行锁定,防止幻行的插入。
2.索引级别:支持多种类型的索引,HASH,BTREE等,InnoDB的表基于聚簇索引建立,意味着除了主键索引其他的索引都会携带主键列,所以如果主键很大的话其他列上的索引也都会很大,这也是主键要求尽量长度较小的原因(说到这给自己挖个坑,主键的生成算法,以后有时间再写)。
3.数据安全,InnoDB之所以成为主流的存储引擎,还有个重要原因是他具备崩溃恢复功能,意味着即使数据在机器崩溃后不会丢失,并且InnoDB支持在线热备份。
4.并发,前面说过InnoDB通过mvcc支持无锁高并发,然而有些操作是必须要上锁的,InnoDB采用行锁处理多线程并发访问,尽量减小锁粒度,读时采用共享锁(shared),修改时采用独占锁(exclusive),类似Java中的读写锁。上面说的这些都是InnoDB主动帮我们完成的,称之为隐式锁定,我们也可以主动使用语句来完成显示锁定,比如锁表"LOCK TABLES ...",锁指定的行 "SELECT..LOCK IN SHARE MODE"或者"SELECT ... FOR UPDATE"(后者在做并发时性能要求不高时可以采用作为悲观锁,更常见的是使用乐观锁,乐观锁的原理同MVCC)。数据库中的锁同Java中的锁一样,使用不当会发生死锁,而与Java不同的是,InnoDB会自动检测死锁并尝试回滚最小的事务来打破死锁
2.MyISAM:
除了InnoDB,用的最多的就是MyISAM了,大家可能听过MyISAM引擎的count(*)速度很快,确实,他不仅在某些情况下速度比较快而且提供了很多特性比如压缩表等,也因为不是聚簇索引表占用空间也比InnoDB小很多。但他有一个致命的缺点,不支持事务与行级锁并且崩溃后无法安全恢复,这意味着在平常的应用开发中我们不会使用该引擎,但他可以用来做一些报表分析,日志分析等应用,数据导入之后,数据不在进行修改操作,在这样的场景下适合使用MyISAM引擎。
3.Memory:
MySQL在执行查询过程中如果需要使用临时表来存储数据,那么数据就存储在Memory表上,如果结果过大超出了限制,则会在转为MyISAM表,Memory由于在内存中,所以速度很快,在做sql优化的时候尽量减小生成临时表的大小。
4.其他
MySQL还有一些其他的引擎,例如CVS引擎,他可以将CVS文件作为MySQL的表来处理,然而该种情况下我们一般都是使用Hadoop来处理。还有Archive等一些引擎,就不说了,这些引擎我们几乎不会用到,应用场景很少,想具体了解的可以去MySQL官网查看。
注:MySQL官方文档关于InnoDB的行为那一章内容很多,干货也很全,通读之后可以大致了解InnoDB的行为,如果有时间的话推荐大家去看一下。