1.概述


InnoDB存储引擎支持两种索引,一种是B+树索引,一种是哈希索引。 InnoDB存储引擎支持的哈希索引是自适应的,InnoDB存储引擎会根据表的使用情况自动为表生成哈希索引,不能人为干预是否在一张表中生成哈希索引。 B+树索引是传统意义上的索引,这是目前关系型数据库系统中最常用、最有效的索引。B+树索引类似于二叉树,根据键值(Key,Value)快速找到数据。需要注意的是,B+树索引并不能找到一个给定键值的具体行,能找到的只是被查找数据行所在的页,然后数据库通过把页读入内存,再在内存中进行查找,最后得到查找数据。


2.B+树索引

在B+树中,所有记录节点都是按照键值的大小顺序存放在同一层的叶节点中,各叶节点指针进行连接。

innoDB 设置全文索引 innodb的索引实现_innoDB 设置全文索引


数据库中的B+树索引可以分为聚集索引和辅助索引(也叫非聚集索引)。

2.1聚集索引


聚集索引就是按照每张表的主键构造一棵B+树,并且叶子节点中存放着整张表的行记录数据,因此也让聚集索引的叶节点成为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。同B+树一样,每个数据页都通过一个双向链表来进行连接。 由于实际的数据页只能按照一棵B+树进行排序,因此每张表只能拥有一个聚集索引。 注:在B+树索引结构中,数据页(即叶节点)存放的是完整的行记录,而在非数据页的索引页中(非叶节点),存放的仅仅是键值以及指向数据页的偏移量。


innoDB 设置全文索引 innodb的索引实现_存储引擎_02

2.2辅助索引


辅助索引,也称为非聚集索引,其叶级别不包含行的全部数据。叶节点除了包含键值以外,还包含一个书签,该书签用来告诉InnoDB引擎,哪里可以找到与索引相对应的行数据。 辅助索引并不影响数据在聚集索引中的组织,因此每张表上可以有多个辅助索引。当通过辅助索引来寻找数据时,InnoDB引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后通过主键索引来找到一个完整的行记录。


innoDB 设置全文索引 innodb的索引实现_innoDB 设置全文索引_03

2.3 B+树索引的管理


索引的创建和删除可以通过两种方法,一种是ALTER TABLE,另一种是CREATE/DROP INDEX。 (1)ALTER TABLE创建索引的语法为: ALTER TABLE table_name ADD {INDEX|KEY} [index_name] [index_type] (index_col_name,...) [index_option] ... ALTER TABLE table_name DROP PRIMARY KEY | DROP {INDEX|KEY} index_name; (2)CREATE/DROP INDEX创建索引的语法为: CREATE [UNIQUE] INDEX index_name [index_type] ON table_name(index_col_name,...) ; DROP INDEX index_name ON table_name; 目前MySQL数据库存在的一个普遍问题是,所有对于索引的添加或者删除操作,MySQL数据库是先创建一张新的临时表,然后把数据导入临时表,删除原表,再把临时表重命名为原来的表名。 InnoDB存储引擎从版本InnoDB Plugin开始,支持一种快速索引创建方法。这种方法只限定于辅助索引,对于主键的创建和删除还是需要重新建一张表。对于辅助索引的创建,InnoDB存储引擎会对表加上一个S锁,在创建的过程中不需要重建表,因此速度极快。但是在创建过程中,由于上了S锁,因此在创建过程中该表只能进行读操作。删除辅助索引操作就更简单,只需要在InnoDB存储引擎的内部视图更新下,将辅助索引空间标记为可用,并删除MySQL内部视图上对于该表的索引定义即可。


3.哈希索引


InnoDB存储引擎中自适应哈希索引使用的是散列表(哈希表)的数据结构。 InnoDB存储引擎使用哈希算法对字典进行查找,其冲突机制采用链式表方法,哈希函数采用除法散列方式。对于缓冲池页的哈希表来说,在缓冲池中的Page页都有一个chain指针,它指向相同哈希函数值的页。而对于除法散列,m的取值为略大于2倍的缓冲池页数量(innodb_buffer_pool_size的值)的质数。 h(k)=k mod m 自适应哈希是由InnoDB存储引擎自己控制的,不过我们可以通过innodb_adaptive_hash_index来禁用或启动此特性,默认为开启。 当在配置文件中启用了参数innodb_adaptive_hash_index后,数据库启动时会自动创建槽数为innodb_buffer_pool_size/256个的哈希表。


此博客内容参考自《MySQL技术内幕—InnoDB存储引擎》