1. 索引的各种存储结构及其优缺点

1.1 二叉树

  1. 优点:
    二叉树是一种比顺序结构更加高效地查找目标元素的结构,它可以从第一个父节点开始跟目标元素值比较,如果相等则返回当前节点,如果目标元素值小于当前节点,则移动到左侧子节点进行比较,大于的情况则移动到右侧子节点进行比较,反复进行操作最终移动到目标元素节点位置。

  2. 缺点:

在大部分情况下,我们设计索引时都会在表中提供一个自增整形字段作为建立索引的列,在这种场景下使用二叉树的结构会导致我们的索引总是添加到右侧,在查找记录时跟没加索引的情况是一样的

1.2 红黑树

  1. 优点:

红黑树也叫平衡二叉树,它不仅继承了二叉树的优点,而且解决了上面二叉树遇到的自增整形索引的问题,从下面的动态图中可以看出红黑树会左旋、右旋对结构进行调整,始终保证左子节点数 < 父节点数 < 右子节点数的规则。

  1. 缺点:

在数据量大的时候,深度也很大。从图中可以看出每个父节点只能存在两个子节点,如果我们有很多数据,那么树的深度依然会很大,可能就会超过十几二十层以上,对我们的磁盘寻址不利,依然会花费很多时间查找。

1.3 Hash

  1. 优点:

对数据进行Hash(散列)运算,主流的Hash算法有MD5、SHA256等等,然后将哈希结果作为文件指针可以从索引文件中获得数据的文件指针,再到数据文件中获取到数据,按照这样的设计,我们在查找where Col2 = 22的记录时只需要对22做哈希运算得到该索引所对应那行数据的文件指针,从而在MySQL的数据文件中定位到目标记录,查询效率非常高。

  1. 缺点:

无法解决范围查询(Range)的场景,比如 select count(id) from sus_user where id >10;因此Hash这种索引结构只能针对字段名=目标值的场景使用。不适合模糊查询(like)的场景。

1.4 B-Tree

既然红黑树存在缺点,那么我们可以在红黑树的基础上构思一种新的储存结构。解决的思路也很简单,既然觉得树的深度太长,就只需要适当地增加每个树节点能存储的数据个数即可,但是数据个数也必须要设定一个合理的阈值,不然一个节点数据个数过多会产生多余的消耗。

1.4.1 B-Tree的一些特点

  • 度(Degree)-节点的数据存储个数,每个树节点中数据个数大于 15/16*Degree(未验证) 时会自动分裂,调整结构
  • 叶节点具有相同的深度,左子树跟右子树的深度一致
  • 叶节点的指针为空
  • 节点中的数据key从左到右递增排列
  1. 优点:

BTree的结构可以弥补红黑树的缺点,解决数据量过大时整棵树的深度过长的问题。相同数量的数据只需要更少的层,相同深度的树可以存储更多的数据,查找的效率自然会更高。

  1. 缺点:

从上面得知,在查询单条数据是非常快的。但如果范围查的话,BTree结构每次都要从根节点查询一遍,效率会有所降低,因此在实际应用中采用的是另一种BTree的变种B+Tree(B+树)。

2. B+Tree—InnoDB中的索引方案

2.1 相对于BTree,B+Tree做了哪些优化?

B+Tree存储结构,只有叶子节点存储数据
。新的B+树结构没有在所有的节点里存储记录数据,而是只在最下层的叶子节点存储,上层的所有非叶子节点只存放索引信息,这样的结构可以让单个节点存放下更多索引值,增大度Degree的值,提高命中目标记录的几率。

这种结构会在上层非叶子节点存储一部分冗余数据,但是这样的缺点都是可以容忍的,因为冗余的都是索引数据,不会对内存造成大的负担。这种结构会在上层非叶子节点存储一部分冗余数据,但是这样的缺点都是可以容忍的,因为冗余的都是索引数据,不会对内存造成大的负担。


InnoDB中的索引是通过目录项所指向的下一层页号来一层一层去缩小搜索范围,从而达到高效的查询的。通过二分法对页内的目录项和目标值进行比对,查出下一层所在页号,再在该页下进行再次搜索,直到到达叶子节点

2.2 索引的存储结构

索引中的目录项其实长得跟我们的用户记录差不多,只不过目录项中的两个列是主键和页号而已,所以InnoDB复用了之前存储用户记录的数据页来存储目录项,为了和用户记录做一下区分,我们把这些用来表示目录项的记录称为目录项记录。

页的组成结构也是一样的(就是我们前边介绍过的7个部分),都会为主键值生成Page Directory(页目录),从而在按照主键值进行查找时可以使用二分法来加快查询速度。


不论是存放用户记录的数据页,还是存放目录项记录的数据页,我们都把它们存放到B+树这个数据结构中了,所以我们也称这些数据页为节点。从图中可以看出来,我们的实际用户记录其实都存放在B+树的最底层的节点上,这些节点也被称为叶子节点或叶节点,其余用来存放目录项的节点称为非叶子节点或者内节点,其中B+树最上边的那个节点也称为根节点。

2.3 聚簇索引

我们上边介绍的B+树本身就是一个目录,或者说本身就是一个索引。它有两个特点:

使用记录主键值的大小进行记录和页的排序,这包括三个方面的含义:

  1. 页内的记录是按照主键的大小顺序排成一个单向链表。

  2. 各个存放用户记录的页也是根据页中用户记录的主键大小顺序排成一个双向链表。

  3. 存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录项记录的主键大小顺序排成一个双向链表。

B+树的叶子节点存储的是完整的用户记录。

所谓完整的用户记录,就是指这个记录中存储了所有列的值(包括隐藏列)。

聚簇索引的优缺点

  • 可以把相关数据保存在一起。
  • 数据访问更快。
  • 使用覆盖索引扫描的查询可以直接使用页节点中的主键值。
  • 如果表在设计和查询的时候能充分利用以上特点,将会极大提高性能。当然,聚簇索引也有它的缺点:
  • 聚簇索引最大限度提高了I/O密集型应用的性能,但如果所有的数据都存放在内存中,聚簇索引就没有优势了。
  • 插入速度严重依赖插入顺序。这也是为什么InnoDB一般都会设置一个自增的int列作为主键。
  • 更新聚簇索引的代价很高,因为会强制InnoDB将每个被更新的行移到新的位置。
  • 如果不安顺序插入新数据时,可能会导致"页分裂"。
  • 二级索引可能会比想象的更大。因为在二级索引的页子节点中包含了引用行的主键列。
  • 二级索引访问可能会需要进行回表查询。

2.4 二级索引

聚簇索引是根据主键比较大小的,而二级索引是通过用户建立索引的字段来比较大小的。

并且B+树的叶子节点存储的并不是完整的用户记录,而只是c2列+主键这两个列的值。目录项记录中不再是主键+页号的搭配,而变成了c2列+页号+主键的搭配。

并且如果需要查询非索引字段的信息,需要拿着主键id回去聚簇索引中查找

2.5 联合索引

在二级索引的基础,采用多个字段进行比较,先根据最左边的索引排一次序,如果存在相同的值,则根据次左边的索引字段进行比较,如此类推。

3. InnoDB的B+树索引的注意事项

B+树的形成过程是这样的

  • 每当为某个表创建一个B+树索引(聚簇索引不是人为创建的,默认就有)的时候,都会为这个索引创建一个根节点页面。最开始表中没有数据的时候,每个B+树索引对应的根节点中既没有用户记录,也没有目录项记录。

  • 随后向表中插入用户记录时,先把用户记录存储到这个根节点中。

  • 当根节点中的可用空间用完时继续插入记录,此时会将根节点中的所有记录复制到一个新分配的页,比如页a中,然后对这个新页进行页分裂的操作,得到另一个新页,比如页b。这时新插入的记录根据键值(也就是聚簇索引中的主键值,二级索引中对应的索引列的值)的大小就会被分配到页a或者页b中,而根节点便升级为存储目录项记录的页。

这个过程需要大家特别注意的是:一个B+树索引的根节点自诞生之日起,便不会再移动。这样只要我们对某个表建立一个索引,那么它的根节点的页号便会被记录到某个地方,然后凡是InnoDB存储引擎需要用到这个索引的时候,都会从那个固定的地方取出根节点的页号,从而来访问这个索引。

深入理解InnoDB(3)—索引的存储结构相关推荐

  1. mysql数据库存储引擎和索引的描述_Mysql InnoDB引擎的索引与存储结构详解

    前言 在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的. 而MySql数据库提供了多种存储引擎.用户可以根据不同的需求为数据表选择不同的存储引擎,用户也 ...

  2. mysql默认存储引擎的索引结构是_InnoDB引擎的索引和存储结构

    在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的. 而MySql数据库提供了多种存储引擎.用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根 ...

  3. MySQL笔记-InnoDB物理及逻辑存储结构

    首先是InnoDB的物理结构 它是B+树,这里有一点要注意的,数据=索引: 叶子结点存放数据.主键.事务ID.回滚指针的. 二级索引最终都会指向主键索引. 在InnoDB引擎中,创建表没有主键,Inn ...

  4. 联合索引会创建几个索引_联合索引在B+Tree上的存储结构及数据查找方式

    来源:SegmentFault 思否社区作者:木子雷 前言: 本篇文章主要是阐述下 联合索引 在 B+Tree 上的实际存储结构. 本文主要讲解的内容有: 联合索引在B+树上的存储结构 联合索引的查找 ...

  5. 联合索引会创建几个索引_联合索引在B+树上的存储结构及数据查找方式

    能坚持别人不能坚持的,才能拥有别人未曾拥有的. 关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 原文首发于该公号,欢迎关注 引言 上一篇文章<MySQL索引那些事>主要讲了MyS ...

  6. mysql联合索引怎么存储_联合索引在B+树上的存储结构及数据查找方式

    能坚持别人不能坚持的,才能拥有别人未曾拥有的. 关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 引言 上一篇文章<MySQL索引那些事>主要讲了MySQL索引的底层原理,且对比了 ...

  7. 第二篇:MySQL之InnoDB物理存储结构

    第二篇:MySQL中InnoDB引擎的物理存储结构 1. 个人理解 看了很多MySQL的书籍和博客,感觉都是互相抄来抄去,把知识点的罗列,讲不清楚前因后果,让人看起来莫名其妙的.所以,我决定从MySQ ...

  8. B+树在MySQL索引的应用和InnoDB的索引优化

    B树索引算法介绍 1.B树 B树又称为多路平衡查找树,它类似普通的平衡二叉树,不同的一点是B树允许每个节点有更多的子节点. B树有如下特点: 具有n个关键字的节点含有(n+1)棵子树 所有键值分布在整 ...

  9. 【MySQL进阶-03】深入理解mysql的索引分类,覆盖索引,覆盖索引失效,回表,MRR

    MySql系列整体栏目 内容 链接地址 [一]深入理解mysql索引本质 https://blog.csdn.net/zhenghuishengq/article/details/121027025 ...

最新文章

  1. 项目Makefile文件模板
  2. 恕我直言,微服务挺好,但不适合你
  3. fluentd mysql_使用Fluentd + MongoDB构建实时日志收集系统
  4. C/C++之数据类型
  5. .process和ProcessFunction(没有整理完)
  6. 2014-11-25nbsp;11:26
  7. 使用prismjs为网站添加代码高亮功能
  8. 【Java】对Java构造器参数问题的若干思考
  9. 斯坦福 CS183 YC 创业课系列中文笔记
  10. 即将上线的Kafka 集群(用CM部署的)无法使用“--bootstrap-server”进行消费,怎么破?...
  11. AlarmManager.setRepeating将不再准确
  12. 每周荐书:京东架构、Linux内核、Python全栈
  13. VC中调用 Excel 的总结
  14. 在线Latex公式编辑器
  15. 微信小程序实现页面按钮分享,右上角三个点分享禁用分享
  16. 拓嘉启远:拼多多行家心得评论的作用
  17. 【问题记录】怎么用python读取CIFAR10数据集?
  18. 披荆斩棘,蜕变从来学吧这里开始
  19. Openstack租户(项目)、用户、角色的概念与管理
  20. 中职升高职c语言程序设计教程课后答案,锦职业技术学院2020年单独招生计算机应用技术专业技能测试考试大纲(中职升高职)...

热门文章

  1. 你必须知道的CSS盒模型,顺利通过阿里面试
  2. 从草根到百万年薪程序员的十年风雨之路,使用指南
  3. 意外收获字节跳动内部资料,已开源
  4. mysql myisam 锁机制_MySQL--MyISAM之锁机制
  5. 匿名函数、冒泡排序,二分法, 递归
  6. Java构造函数的深入理解
  7. 【9303】平面分割
  8. 使用css3属性transition实现页面滚动
  9. 网管的自我修养-网络系统
  10. python(1) - 数据类型和变量