热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQL(InnoDB剖析):InnoDB索引概述、数据结构与算法概述(二分查找、二叉搜索树、平衡二叉树、B+树)

一、索引概述索引是应用程序设计和开发的一个重要方面。若索引太多,应用程序的性能可能会受到影响。而索引太少,对查询性能又会产生影响。要找到一个平衡点二、InnoDB存储引擎索引概述I

一、索引概述

  • 索引是应用程序设计和开发的一个重要方面。若索引太多,应用程序的性能可能会受到影响。而索引太少,对查询性能又会产生影响。要找到一个平衡点


二、InnoDB存储引擎索引概述

  • InnoDB支持以下几种常见的索引:

    • B+树索引

    • 全文索引

    • 哈希索引


  • 前面已经提到过,InnoDB支持的哈希索引是自适应的InnoDB存储引擎会根据表的使用情况自动为表生成哈希索引,不能人为干预是否在一张表中生成哈希索引

  • B+树索引是传统意义上的索引这是目前关系型数据库中查找最为常见和最有效的索引。B+树索引的构造类似于二叉树,根据键值快速找到数据


  • 注意:B+树索引并不能找到一个给定键值的具体行。B+树索引能找到的只是被查找数据行所在的页。然后数据库通过把页读入内存,再在内存中进行查找,最后得到查找的数据


三、二分查找法

  • 二分查找法(binary search)也称为折半查找法,用来查找一组有序的记录数组中的某一记录,其基本思想是:将记录按有序化(递增或递减)排列,在查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半








演示案例



  • 如有5、10、19、21、31、37、42、48、50、52这10个数,现在要从这10个树中查找48这条记录,其查找过程如下:


  • 从上图可以看到,用来3此就查找到了。如果是顺序查找,则需要8次。如果要查找5这条记录,顺序查找只需1次,二分查找法需要4次

  • 对于上面10个数来说,平均查找次数为(1+2+3+4+5+6+7+8+9+10)/10=5.5次。二分查找法为(4+3+2+4+3+1+4+3+2+3)/10=2.9次。在最坏的情况下,顺序查找的次数为10,而二分查找的次数为4




  • 二分查找法的应用及其广泛。在前面也介绍过,每页PAGE Directory中的槽是按照主键的顺序存放的,对于每一条具体记录的查询是通过对Page Directory进行二分查找的


四、二叉搜索树

  • 定义:

    • 二叉搜索树是一棵二叉树

    • 左子树的键值都小于父节点的键值

    • 右子树的键值都大于父节点的键值


  • 例如下面就是一颗二叉搜索树


查找复杂度



  • 查找5这个节点:

    • 那么先从跟查找,然后再查找左子树3,然后再查找右子树5,最终找到。一共找了3次

    • 如果通过中序遍历的话也需要3次


  • 查找8这个节点:

    • 先找6,再找7,再找8,最终找到。一共找了3次

    • 如果通过中序遍历的话需要6次


  • 总结:

    • 二叉树的平均查找次数为(3+3+3+2+2+1)/6=2.3次

    • 中序遍历的查找次数为(1+2+3+4+5+6)/6=3.3次

    • 因此,二叉搜索树的平均查找速度较快




五、平衡二叉树

  • 平衡二叉树是根据二叉搜索树改进的一种树,例如我们有2、3、5、6、7、8这几个节点,通过下图所示的结构来建立二叉查找树,图中的平均查找次数为(1+2+3+4+5+5)/6=3.16次。因此查找效率比较低


  • 平衡二叉树的定义:

    • 也是一颗二叉查找树

    • 但是左右子树的高度差最大为1,不能超过1,如果超过1,那么就不平衡了




单旋转


  • 在上图所示的平衡二叉搜索树中插入节点9,那么就不是平衡的了,因为节点7的的左右子树高度差为2


  • 因此需要做一次单旋转来回到平衡状态



双旋转


  • 在上图所示的平衡二叉搜索树中插入节点3,那么就不是平衡的了,因为节点2的的左右子树高度差为2


  • 因此需要做双旋转来回到平衡状态


六、B+树

  • B+树和二叉树、平衡二叉树一样,都是经典的数据结构。B+树由B树和索引顺序访问方法(ISAM,这就是MyISAM引擎最初参考的数据结构)演化而来,但是在实现使用过程中几乎已经没有使用B数的情况了

  • 下面我们对B+数进行精简的讲述:B+树是为磁盘或其他直接存储辅助设备设计的一种平衡查找树,由各叶子节点指针进行连接。先来看一个B+数,其高度为2,每页可存放4条记录,扇出(fan out)为5,图下图所示

  • 从下图可以看出,所有记录都在叶子节点上,并且是顺序存放的,如果用户最坐左边的叶子节点开始顺序遍历,可以得到所有键值的顺序排列:5、10、15、20、25、30、50、55、60、65、75、80、85、90


B+树的插入操作



  • B+树的插入必须保证插入后叶子节点中的记录依然排序,同时需要考虑插入到B+树的三种情况,每种情况都可能会导致不同的插入算法。如下图所示:

Leaf Page未满、Index Page未满的插入



  • 对于上面那张B+树所示,若用户插入28这个键值,因为Leag Page和Index Page都未满,因此可以直接插入,得到下图所示结果

Leaf Page已满、Index Page未满的插入



  • 接着上图,我们再插入70这个键值,此时Leag Page已满但是Index Page未满,插入之后Leaf Page的情况为:50、55、60、65、70,此时中间节点为60,以60来拆分叶子节点

  • 此时根据以下规则插入:

    • 查分Leaf Page

    • 将中间的节点(60)放入到Index Page中

    • 小于中间节点的记录(50、55)放左边

    • 大于或等于中间节点的记录(65、70)放右边


  • 最终的结果过如下图所示(备注:下图没有在各叶子节点加上双向链表指针,不过与上图一样,它是存在的):

Leaf Page已满、Index Page已满的插入



  • 接着上图,我们插入键值95,此时Leag Page、Index Page都已满,因此需要做两次拆分,执行步骤如下:

    • 拆分Leaf Page

    • 小于中间节点的记录放左边

    • 大于或等于中间节点的记录放右边

    • 拆分Index Page

    • 小于中间节点的记录放左边

    • 大于中间节点的记录放右边

    • 中间节点放入上一层Index Page




旋转操作



  • 从上面可以看到,不论B+树如何变化,最终都会平衡。因为B+树会不断进行拆分页操作。但是B+数主要用于磁盘,页的拆分意味着磁盘的操作,所以应该在可能的情况下尽量减少页的拆分操作,所以B+树也提供了类似于平衡二叉树的旋转操作

  • 原理:


    • 旋转发生在Leaf Page已满,但是其左右兄弟节点没有满的情况下

    • 这时B+树并不会急于去做拆分页的操作,而是将记录移动到所在页的兄弟节点上

    • 在通常情况下,左兄弟会被首先检查用来做旋转操作


  • 再来看看上面“Leag Page未满、Index Page未满的插入”,如下图所示:


  • 若插入键值70,其实B+树并不会急于拆分叶子节点,而是做旋转操作,得到下图所示的操作



B+树的删除操作



  • B+树使用填充因子(fill factor)来控制树的删除变化,50%是填充因子可设的最小值

  • B+树的删除操作同样必须保证删除后叶子节点中的记录依然排序

  • 同插入一样,B+树的删除操作同样需要考虑下面的3种情况,与插入不同的是,删除根据填充因子的变化来衡量

表中删除的第一种情况(删除节点为叶子节点)



  • 例如根据上图,我们要删除70这条记录。因为70为叶子节点,因此直接删除这个叶子节点即可

  • 最终的结果如下

表中删除的第一种情况(删除节点非叶子节点)



  • 接着上图,我们删除键值为25记录,但是该值还是Index Page中的值,因此删除之后要以其右兄弟节点(2)来代替。最终的结果如下

表中删除的第一种情况



  • 接着上图,我们要删除60这个节点

  • 删除Leaf Page中键值为60的记录后,File Factor小于50%,这时需要做合并操作,同样,再删除Index Page中相关记录后需要做Index Page的合并操作,最终的结果如下:






推荐阅读
  • 本文探讨了2012年4月期间,淘宝在技术架构上的关键数据和发展历程。涵盖了从早期PHP到Java的转型,以及在分布式计算、存储和网络流量管理方面的创新。 ... [详细]
  • 网易严选Java开发面试:MySQL索引深度解析
    本文详细记录了网易严选Java开发岗位的面试经验,特别针对MySQL索引相关的技术问题进行了深入探讨。通过本文,读者可以了解面试官常问的索引问题及其背后的原理。 ... [详细]
  • HBase运维工具全解析
    本文深入探讨了HBase常用的运维工具,详细介绍了每种工具的功能、使用场景及操作示例。对于HBase的开发人员和运维工程师来说,这些工具是日常管理和故障排查的重要手段。 ... [详细]
  • 本文详细介绍了如何查找和更改 MySQL 数据库文件的存放路径,包括不同存储引擎的配置方法以及具体操作步骤。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 通过Web界面管理Linux日志的解决方案
    本指南介绍了一种利用rsyslog、MariaDB和LogAnalyzer搭建集中式日志管理平台的方法,使用户可以通过Web界面查看和分析Linux系统的日志记录。此方案不仅适用于服务器环境,还提供了详细的步骤来确保系统的稳定性和安全性。 ... [详细]
  • 堆是一种常见的数据结构,广泛应用于计算机科学领域。它通常表示为一棵完全二叉树,并可通过数组实现。堆的主要特性是每个节点的值与其父节点的值之间存在特定的关系,这使得堆在优先队列和排序算法中非常有用。 ... [详细]
  • 本文详细介绍了如何解决OBS在全屏录制时出现黑屏的问题,并提供了关于正确配置显卡以实现高效推流的指导。通过调整操作系统和显卡设置,确保OBS能够稳定运行并提供高质量的直播或录制体验。 ... [详细]
  • 探讨如何从数据库中按分组获取最大N条记录的方法,并分享新年祝福。本文提供多种解决方案,适用于不同数据库系统,如MySQL、Oracle等。 ... [详细]
  • 2018年3月31日,CSDN、火星财经联合中关村区块链产业联盟等机构举办的2018区块链技术及应用峰会(BTA)核心分会场圆满举行。多位业内顶尖专家深入探讨了区块链的核心技术原理及其在实际业务中的应用。 ... [详细]
  • 开发笔记:9.八大排序
    开发笔记:9.八大排序 ... [详细]
  • 本文探讨了如何使用自增和自减运算符遍历二维数组中的元素。通过实例详细解释了指针与二维数组结合使用的正确方法,并解答了常见的错误用法。 ... [详细]
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
  • 给定行数 numRows,生成帕斯卡三角形的前 numRows 行。例如,当 numRows 为 5 时,返回的结果应为:[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]。 ... [详细]
  • 本文探讨了如何在iOS开发环境中,特别是在Xcode 6.1中,设置和应用自定义文本样式。我们将详细介绍实现方法,并提供一些实用的技巧。 ... [详细]
author-avatar
寡凫lo单鹄官方
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有