Mysql底层数据结构与算法

索引

是一种已经排好序的数据结构,常用的类型有以下几种

  • 二叉树
  • 红黑树
  • Hash表
  • B树
  • B+树

数据结构图形化界面:Data Structure Visualization

二叉树

又称为二叉查找树,是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,且当前节点大于左子树并小于右子树,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点。

值不断增大插入的时候,新插入的值会作为右子树,此时的二叉树就像一个单向链表

数据插入时,会不断的和每一个节点进行比较,若小于则放在当前节点的左子树,大于则放在右子树

 

mysql未将它作为索引的数据结构,原因是查询的效率太慢了;若一张表中的数据量太大可能就需要遍历整个二叉树来进行查找,而索引文件是存在磁盘中的,查询次数过多的IO操作及其耗费时间。

AVL树(平衡二叉树)

它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

举例按顺序插入 1,2,4 ,构造出来的结果会如下所示

插入1,2

插入4

相比较二叉查找树,平衡二叉树会在插入元素后检查左右子树的高度差,若超过1,则会进行平衡,按照二叉树的特性进行旋转

 

红黑树

红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组,红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树,但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。

特点

  • 结点是红色或黑色。
  • 根结点是黑色。
  • 所有叶子都是黑色。(叶子是NIL结点)
  • 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
  • 从任一节结点到其每个叶子的所有路径都包含相同数目的黑色结点

和AVL树一样,红黑树也会保持平衡

B树

相比较二叉树和红黑树,一个节点只能存放一个元素,B树的每一个节点是可以存放多个索引+数据的,就像一个元素和一个数组的区别

 

特点

  • 叶节点具有相同的深度,叶节点的指针为空
  • 所有索引元素不重复
  • 节点中的数据索引从左到右递增排列

 

在mysql的设定中,一个节点可存储的数据量为16kb,但B数的节点不仅仅存储索引,还存储了该索引对应的数据行的数据,因此,在使用B树的时候,每一个节点可以存放的索引数量不会很多;在表数据量越大的情况下,B树的高度会越高,故在查询的时候会越慢

B+树

特点

  • 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
  • 叶子节点包含所有索引字段
  • 叶子节点用指针连接,提高区间访问的性能

在mysql中的数据结构

 

和B树的区别在于,非叶子节点没有数据,只存储索引(存在冗余),在相同的存储容量的条件下,每个非叶子节点可存储的索引数量=16K/索引大小(占用的空间很小,以16B为例),每增加一个高度,可存储的数据量就变为原来的1024(16K/16B)倍;并且在B+数中的叶子节点中存储着指向上、下叶子节点的指针,用来加快查询速率。

Hash表

特点

  • 对索引的key进行一次hash计算就可以定位出数据存储的位置
  • 很多时候Hash索引要比B+ 树索引更高效
  • 仅能满足 “=”,“IN”,不支持范围查询
  • hash冲突问题

存储引擎

存储引擎就是指表的类型以及表持久化存在磁盘的存储方式,它是针对表的一种处理方式,当然,数据库也有存储引擎,但一般都是指的表的存储,一般情况下mysql默认的存储引擎是innodb。

MyISAM存储引擎索引实现

使用MyISAM使用时,其索引文件和数据文件是独立分离的,其特点是存储快查询慢,故现在大部分对查询要求比较高的业务场景都是使用innoDB的存储引擎。

InnoDB存储引擎索引实现

  • 表数据文件本身就是按B+Tree组织的一个索引结构文件
  • 聚集索引-叶节点包含了完整的数据记录

建议InnoDB表必须建主键的理由:主键的特点就是主键的值不可重复,也不可为空,正好符合B+树key的要求,而如果表中没有主键,会选择一个唯一的非空索引来代替主键构建B+树;若表中连索引都没有,则会使用一个隐式的定义一个不可见的列来作为主键,用以构建B+树。

并且推荐使用整型的自增主键原因:使用整型的原因在于,B+树是有序存储的,在构建索引的时候,整型的排序对比显然要比字符类型的逐位比较快的多;而使用自增的原因在于,在索引插入的时候,自增的主键会直接在尾部插入,若是非自增的,插入的时候就要遍历查找该新增项的数值位于B+树的哪一个节点,相比直接的尾部插入要更耗费资源。

假设现在有一张InnoDB的表,存储了id、age、name等列,且id作为主键。

主键索引

非主键索引

 

 

非主键索引结构叶子节点存储的是主键值原因:对于innoDB的表来说,只有一个以唯一主键作为聚集索引的B+树,而非主键索引存储的数据则是,以主键作为索引的B+树的索引列,这样更能节省存储空间,也能保持数据一致性。

索引最左前缀原则

联合索引存储结构

由多个字段组合成的一个索引称之为联合索引,其底层也是一个B+数,相比于单列索引,联合索引会按照索引建立的顺序来对表中的数据进行排序,比如建立索引时是(id,age,name),那么在排序的时候就会先比较id然后比较age,最后比较name,就类似mysql中的order by排序,会根据后面的列依次进行。

 

为何联合索引使用时会要最左匹配,原因在于索引的数据结构就是一种已经排好了顺序的数据集合;若不按索引建立的顺序来使用,查询时就无法通过索引来快速的定位到需要的数据

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值