MySQL索引及存储引擎

一 MySQL索引

1.什么是索引

索引在MySQL中也叫做键,是存储引擎用于快速查找数据的一种数据结构。

2.索引的数据结构

数据结构的作用:每次查找时把磁盘IO控制在一个很小的数量级,最好是常数级。

索引的数据结构采用B+树。

(1)为什么说B+树比B树更适合做索引?

B树在提高IO性能的同时并没有解决遍历效率低下的问题,但B+树解决了这个问题,B+树的遍历只需要遍历叶子节点的链表结构就可以遍历完整棵树,提高了性能,而且在数据库中基于范围的查找是很频繁的,但B树却不具备这样的操作。

更详细的说:

•B+树的磁盘读写代价更低。B+树内部节点没有指向关键字具体数据的指针,因此B+树的内部节点比B树小,如果把所有节点的统一关键字信息存储在同一磁盘块中,B+树可以比B树存储更多,相对IO次数也就更少。

•B+树的查找更加稳定。由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

•B+树的数据都存储在叶子节点中,方便扫描库,只需要扫描一遍叶子节点就可以 。但B树的分支节点同样存储着数据,要找到具体的数据,需要进行中序遍历来扫描,所以B+树更适合在区间进行查找

3.B+树

MySQL索引及存储引擎_第1张图片

上图就是B+树的结构,B+树是为了应文件系统所需而产生的一种B树的变形树,在B+树中只有叶子节点保存数据,非叶子节点保存索引,不保存实际的数据。在叶子节点中使用链表把所有实际数据链接在一起,使得遍历整棵树的时候只需要遍历叶子节点的链表结构就可以。

(1)B+树的查找过程

以上图为例,浅蓝色代表磁盘块,一个磁盘块中包含数据(深蓝色)和指针(黄色),此时的数据并不是实际数据,相当于索引,实际数据存放于叶子节点中(3,5,9,10,13,15,28,29,36,68,75,79,90,99),P1代表小于17的部分,P2代表位于17-35之间,P3代表大于35。B+数的查找实际上是在内存中利用二分查找法,比如要查找15,首先先把磁盘块一加载到内存,此时发生一次磁盘IO,发现15小于17,那么就锁定P1,通过P1指针,把磁盘块2加载到内存,此时发生一次磁盘IO,在磁盘块2中,15大于12,锁定P3,通过P3找到磁盘块7加载到内存,此时发生一次磁盘IO,在磁盘块7中在利用二分查找,找到15,查找结束。

通过查找过程可以发现,磁盘的IO次数与B+树的高度相关,B+树的高度越高,磁盘IO次数越多,查找效率就越低。

(2)B+树的性质

•索引字段尽量要小

  对于B+树来说,磁盘块的大小是固定的,所以索引字段尽量小的时候,每个磁盘块能存储的索引字段数量就会更多,这样B+树的高度就会更低,而B+树的高度会决定磁盘的IO次数,高度越低,磁盘IO次数就会越少,效率就会越高。这也是为什么B+树要求把真实的数据存放到叶子节点的原因,一旦把数据存放到内层节点,磁盘块的数据项会大幅下降,导致树增高。

•索引采用最左匹配原则

当B+树的数据是复合结构的时候,B+树是采用从左到右的方式建立搜索树的,比如,(name,age,sex),现有数据(小明,20,F),当B+树建立搜索树的时候,会先比较name,找到小明后,才会比较age,sex,但如果字段为(20,F),此时B+树就无从下手了,因为建立搜索树的时候第一个字段是name,当缺失第一个字段的时候,B+树就不知道该如何建立搜索树了,但如果是(小明,F),此时B+树仍可以建立搜索树,虽然缺失了age,但可以把名字为小明的数据都找到,然后再找sex为F的数据,这就是最左匹配原则。

4.MySQL的索引分类

(1)普通索引:加速查找

(2)唯一索引:包括唯一索引和主键索引,用于加速查找,约束。

(3)联合索引:联合普通索引,联合唯一索引,联合主键索引。

(4)全文索引:适用于查找一篇比较长的文章。

(5)空间索引:不常用

5.索引的两大类型

(1)Hash类型:查询单条速度快,查询范围速度慢。

(2)Btree类型:B+树,InnoDB默认支持。

二 MySQL存储引擎

1.定义

数据库引擎是用于存储,处理和保护数据的核心服务。利用数据库引擎可控制访问权限并快速处理事务,从而满足企业内大多数需要处理大量数据的应用程序的要求。

2.存储引擎作用

(1)设计并创建数据库以及保存系统所需的关系或XML文档。

(2)实现系统以访问和更改数据库中存储的数据。

(3)部署实现的系统。

(4)提供日常管理支持以优化数据库的性能。

3.MySQL存储引擎

Mylsam InnoDB  Memory Blackhole  CSV Performance_Schema

Archive Federated Mrg_Myisam

这里主要介绍了前三个。

3.1 InnoDB

(1)定义

 默认的存储引擎(Mysql在V5.1之前默认存储引擎是MyISAM;在此之后默认存储引擎是InnoDB)。

InnoDB是一个事务型的存储引擎,它支持行级锁定和外键锁定,提供了数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别,InnoDB的设计目的是为了大容量数据库系统。MySQL运行时,InnoDB会在内存中建立缓冲池来用于缓冲数据和索引,但InnoDB不支持FULLTEXT类型的索引,也没有保存表的行数,InnoDB的写操作不会锁定全表,所在在高并发的时候使用InnoDB会提高效率,但InnoDB并不是所有情况下都不进行全表锁定,当MySQL不能确定扫描范围的时候,InnoDB就会进行全表锁定。

(2)适用场景

• 经常更新的表,适合处理多重并发的更新请求。

• 支持事务

• 可以从灾难中恢复(通过bin-log日志)。

• 外键约束。(只用InnoDB支持外键)

• 支持自动增加列属性auto_increment。

(3)InnoDB使用的索引类型

InnoDB使用的是聚簇索引。

InnoDB的一个数据表中,它的索引文件和数据文件是同一个,也就是说,在查询时只要找到了索引就找到了数据文件。在InnoDB中及存储主键索引值,有存储行数据,叫做聚簇索引 。

聚簇索引实际上是对磁盘数据重新组织以按照一列或多列的值进行排序的一种算法。聚簇索引的特点是存储的顺序和索引的顺序一致,一般情况下主键会默认创建聚簇索引,且一张表中值存在一个聚簇索引,因为数据一旦存储,顺序只有一个。

聚簇索引和非聚簇索引的区别:

聚簇索引的叶子节点就是数据节点,非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。

(4)InnoDB中一张表中聚簇索引的建立

•  有主键时,根据主键创建聚簇索引

•  没有主键时,会用一个唯一且不允许为空的索引列做为主键,成为此表的聚簇索引

•  如果以上两个都不满足那innodb自己创建一个虚拟的字段为主键,这个字段长度为6个字节,类型为长整形,根据该虚拟主键创建聚集索引

3.2 MyIsam

(1)定义

MyIsam是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此写操作需要锁定整个表,效率便会低一些。MyIsam独立于操作系统,可以在Windows上使用,也可以简单的将数据移到Linux上。

MyIsam在创建表的时候回建立三个文件,一个是.frm用来存储表的定义,一个是.MYD文件用来存储表的数据,一个是.MYI文件,用来存储索引。操作系统对于大文件的操作是比较慢的,这样将表分为三个文件,那么.MYD这个文件单独来存放数据自然可以优化数据库的查询等操作。

(2)适用场景

•  不支持事务的设计,但是并不代表着有事务操作的项目不能用MyIsam存储引擎,可以在service层进行根据自己的业务需求进行相应的控制。

•  不支持外键的表设计。

•  查询速度很快,如果数据库查询的操作比较多的话比较适用。

•  频繁对表进行加锁的场景。

•  MyISAM极度强调快速读取操作。

•  如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。

(3)MyIsam使用的索引方法

非聚簇索引。

非聚簇索引又叫二级索引。二级索引的叶子节点中保存的不是指向行的物理指针,而是行的主键值。当通过二级索引查找行,存储引擎需要在二级索引中找到相应的叶子节点,获得行的主键值,然后使用主键去聚簇索引中查找数据行,这需要两次B-Tree查找。

3.3 Memory

(1)定义:

使用存在内存中的内容来创建表。每个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH索引。

但是一旦服务关闭,表中的数据就会丢失掉。 HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。在数据行被删除的时候,HEAP也不会浪费大量的空间。HEAP表格在你需要使用SELECT表达式来选择和操控数据的时候非常有用。

Memory同时支持散列索引和B树索引,B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符方便数据挖掘,散列索引相等的比较快但是对于范围的比较慢很多。

(2)特性要求:

1)要求存储的数据是数据长度不变的格式,比如,Blob和Text类型的数据不可用(长度不固定的)。

2)在用完表格之后就删除表格。

三 数据库事务及隔离级别

1.数据库的四个事务ACID

A:原子性

原子性指事务要么成功,要么全部失败回滚。

C:一致性

一致性指事务必须使数据库从一个一致性状态转到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

I:隔离性

隔离性值多个并发事务之间相互隔离,比如现在有两个并发事务T1,T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发的执行。

D:持久性

指数据库事务一旦被提交,对数据库的改变就是永久的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

2.事务隔离级别

(1)MySQL提供四种隔离级别:

读未提交,读已提交,可重复读,串行化。

读未提交:最低级别,任何情况都无法保证。

读已提交:可避免脏读。

可重复读:可避免脏读,不可重复读。

串行化:最高级别,可避免脏读,不可重复读,幻读的发生

级别越高,执行效率就越低。串行化就是以锁表的方式使得其他线程只能在锁外等待,所以平时选用所以平时选用何种隔离级别应该根据实际情况。MySQL数据库中默认的隔离级别是可重复读。

(2)如果不考虑事务隔离性,将发生以下问题:

脏读:

指事务在处理过程中读取了另一个未提交的事务的数据。

当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。

不可重复读:

指对于数据库中的某个数据,在一个事务范围内多次读取却返回不同的数据值,这是由于在查询的间隔,被另一个事务修改并提交了。

例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

不可重复读和脏读的区别是,不可重复读是读取了前一事务已经提交的数据,而脏读是读取了另一个事务未提交的数据。

幻读:

幻读是事务非独立执行时发生的状况。比如事务T1对表中所有的行的某个数据进行从1变为2的修改,这是事务T2对这个表进行了一个插入操作,插入的数据刚好是2,此时T1在读取就会发现有一行没有修改,其实是T2添加的,这时就发生了幻读。

幻读和不可重复读的区别是,幻读针对的是一批数据整体,而不可重复读查询的是同一个数据项。

你可能感兴趣的:(MySQL索引及存储引擎)