MySQL底层数据结构与算法

MySQL底层数据结构

索引是帮助MySQL高效获取数据的排好序的数据结构

Hash表
二叉树
红黑树
B-Tree(B树)

-------------------------------------------------------------------------------------------------------------------------

各种结构

Hash表

  • 对索引的key进行一次hash计算就可以定位出数据存储的位置
  • 比B+树要高效,因为计算一次就可以的得出数据位置,但是会存在Hash冲突。
  • 只能满足“=”,“in",不支持范围查找

MySQL底层数据结构与算法_第1张图片

-------------------------------------------------------------------------------------------

二叉树

二叉树

  • 每个节点至多只有二棵子树,左子树和右子树,次序不能颠倒。
  • 逻辑上二叉树有五种基本形态:空二叉树、只有一个根结点的二叉树、只有左子树、只有右子树、完全二叉树(特例为满二叉树)。
  • 遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次,有前序、中序、后序遍历。

平衡二叉树

  • 在二叉树的基础上,对二叉树的高度做一个平衡处理,常见的有红黑树
  • 通过红黑节点,左旋转,右旋转,达到一个平衡,查找效率必二叉树高且稳定

但随着数据量的增多,平衡二叉树树的高度会越来越高,大概1000条数据就有9 - 10层,那也就是说可能找一个数据需要9 -10次 IO。
那假如1万条,百万条数据呢?

那有没有方法解决高度过高的情况呢?
那肯定是必须的呀,所以有B-Tree以及B+Tree,尽可能往节点中塞进更多的数据,当然不是越多越好。

-------------------------------------------------------------------------------------------

B-Tree和B+Tree

为了解决高度过高的问题,在节点中放入m个孩子,从而减少树的高度,减少磁盘IO.

B-Tree(B树)

多路搜索树,每个节点有多个孩子。

  • 叶节点具有相同的深度,叶节点的指针为空
  • 所有索引元素不重复
  • 节点中的数据索引从左到右递增排序
  • 数据与索引存储在同一地方。
    MySQL底层数据结构与算法_第2张图片
    那么 MySQL 是选择了B+Tree,而不选择B-Tree呢,让我们看看B+Tree的结构,比对一下。

B+Tree(B+树) B树的升级版

  • 非叶子节点不存储数据,只存储索引,节约空间,放更多的索引
  • 叶子节点包括所有的索引,从左到右递增
  • 叶子节点用指针连接,提高区间访问的性能。
  • 数据都只存储在叶子节点中
    MySQL底层数据结构与算法_第3张图片

B-Tree与B+Tree比对:

✖不同点:

  • 索引是否重复,B-Tree索引节点不重复,B+Tree索引节点会有重复,其叶子节点包含所有的数据。
  • 数据存储的位置,B-Tree 存储在索引上,B+Tree只存储在叶子节点上。
  • B+Tree叶子节点做了双向指针链表,若取区间范围数据有奇效。

✔相同点:

  • 都是从左到右有序排序。
  • 都引入了单节点多孩子的概念。
  • 都能有效降低树的高度

看完这两个比对,就知道为什么MySQL选择B+Tree。
其中B+Tree的优化就是能更大程度的降低树的高度,非叶子不存数据,让节点尽可能在有限的空间中塞进更多的孩子。
也包括其叶子节点是一个有序的双向链表,在区间搜索有一定的优势。

-------------------------------------------------------------------------------------------

MySQL底层数据结构:B+Tree

为什么 B+tree 不在非叶子结点存储除索引外的其他数据呢?
答: 为了继续降低树的高度,同时让非叶子结点可以存储更多的索引。
一个节点有其固定的容量大小,如果在相同的容量下,可以存储更多的索引,那么树的高度就会下降,遍历次数变小,搜索将会变快。

-------------------------------------------------------------------------------------------

MySQL的两种数据引擎

  • MyISAM
  • InnoDB

我们常听到什么聚集索引非聚集索引,其实区分他们仅需要知道他们的底层数据存储的索引文件数据文件是不是分开的。
索引和数据都存储在一个地方,他就是聚集索引
索引和数据不存储在同一个地方,他就是非聚集索引

InnoDB 存储引擎两个文件分别存储:

  • frm:表结构文件
  • ibd:表索引及数据文件

MyISAM 存储引擎三个文件分别存储:

  • frm:表数据结构文件
  • MYI:表索引文件
  • MYD:表数据文件

MyIsam存储引擎

MyISAM 存储引擎底层使用的是 B+tree,叶子结点只存储了所有的索引 + 数据的磁盘地址。
因此索引文件和数据文件是分离的,它是非聚集索引

MySQL底层数据结构与算法_第4张图片

InnoDB存储引擎(聚集)

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

MySQL底层数据结构与算法_第5张图片

-------------------------------------------------------------------------------------------

为什么会建议 InnoDB 表必须建主键❓

  • innodb存储引擎他是如果你没有创建索引,他会自动帮你找一列数据,这列数据没有重复的,把这个当成索引,然后在这个里面进行存储.
  • 但是万一这个表找不到这个字段,他会自动帮你在底层创建一个隐藏的主键,这个就是int类型,通过这个隐藏键将这个数据按照B+树方式进行存储
  • 所以在建表时候自己能把主键建了就建了,别老是让MySQL底层帮你创建,他这个innodb就是这么设计的
  • 所以innodb存储引擎的表自己创建一个主键,这样MySQL也能够节省损耗

为什么推荐使用整型的自增主键❓

自增整型排序效率高,使用整形自增主键情况下,数据只需要一直往叶子结点后面放即可,大大减少索引页的分裂和移动数据产生的磁盘开销。

-------------------------------------------------------------------------------------------

都看到这里了,能给赞吗,谢谢!

你可能感兴趣的:(MySQL,mysql)