MySQL索引底层数据结构与算法

前言:

      数据库是每个程序员都必须要掌握的技能,数据库中的数据能被快速查找到是离不开数据库索引,那我们来了解一下mysql索引底层的数据结构。

什么是索引:

        索引都是排好序的数据结构。        

索引的数据结构:

       二叉树:按照索引存储的话会变成数组,效率几乎没有提升。

       红黑树:高度不可控。(会自适应调整树结构,耗性能)

       Hash表: 不支持范围查找。

       B-Tree:数据库使用(B树的变种 b+tree)。

以上是可以用来做为索引的数据结构,mysql实际使用的是B+tree。

什么是B+tree?

          在了解B+tree之前,我们先了解一下什么是B树,为什么mysql不使用B树作为索引的底层数据结构呢?

 以上就是B树这种数据结构

B树的特点是:

        1.叶节点具有相同的深度,叶节点的指针为空

        2.所有索引元素不重复

        3.节点中的数据索引从左到右递增排列

然后我们再来看一看B+tree的数据结构

 B+tree的特点:

        1.非叶子节点只不存储data,只存储索引(冗余),可以放更多的索引

        2.叶子节点包含所有索引字段

        3.叶子节点用指针连接,提高区间访问的性能。(可以更好的支持范围查找)

解析:

       上述两种数据结构的节点都是16kb的空间,也就是对应mysql的一页数据,以B+tree为例,我们算一下根节点可以存储多少的索引,主键假设为bigint,占用8个b,再加上存储下一个节点的地址大概6个b,算下来跟节点可以存16kb*1024/14 = 1170,也就是一个根节点可以存1170个索引,如果是三层,叶子节点因为有data数据,假设一条数据1kb,也就是叶子节点可以存储16条数据,那么存储的索引数量为1170*1170*16差不多2100w条数据。并且B+tree可以很好的支持范围查找。三层树高完成可以支撑大部分场景,如果数据真的非常大,那我们应该考虑分库分表等方案来提高我们数据库的性能。

        通过以上,我们可以得出,B+tree更契合mysql索引。

总结B-tree(B树) 和B+Tree的区别:

       1. B树的叶子节点没有指针,不能很好的支持范围查找

       2. B+Tree底层叶子节点有双向指针,方便进行范围查找

       3. B+Tree将所有的数据都挪到了叶子节点

       4. 同样存储一定的数据,B+tree可以控制树的高度,但是B树的高度可能已经非常高了,远远大于B+Tree的高度

       5. B+Tree的叶子节点有冗余数据


         上述我们介绍了mysql索引底层数据结构以及主键索引,接下来我们介绍一下mysql的二级索引(非主键索引),我们以联合索引来举例子:

         注:mysql除了主键索引会有索引树外,也会有别的索引树,我们可以这种索引为非主键索引/二级索引等等,除主键索引树叶子节点存储的是data数据外,其他索引树叶子节点都会存储一个对应主键索引的地址,非主键索引(二级索引)的叶子节点存放的是主键索引地址,然后查找到这个叶子节点的主键再回表去取数据。这种只有主键索引存储数据的方式,可以有效的节省空间。

        学习上述联合索引,我们需要先知道最左前缀原则,什么是最左前缀原则,简单来说就是按照索引字段的构建顺序,比如上述,先按照name比较大小,如果相同再按照age比较大小,如果age也相同,就按照position比较大小。(mysql索引都是B+tree结构)


扩展

什么是聚集/聚簇索引?什么是非聚集/非聚簇索引?

       讨论这个问题,我们需要结合存储引擎来说明,以MyISAM存储引擎来说,他就是非聚集/非聚簇的(两者是一回事),为什么这么说,是因为使用MyISAM存储引擎的表会生成三个文件,分别是以.frm结尾的存储表结构文件 ,以.myd结尾的存储表数据内容,以 .myi结尾的存储表索引,它在查找数据时,需要先从.myi文件中找到对应的索引地址,然后通过该地址去数.myd文件中找到对应的数据返回。表的索引跟数据不在同一个文件,所以是非聚集/非聚簇索引。

        同理 InnoDB存储引擎是聚集/聚簇索引,会生成两个文件,分别是以.frm结尾的存储表结构文件 ,以.ibd结尾的存储数据和索引文件。查找数据时,只需要在一个文件中找到对应索引位置,即可拿到对应data数据。所以是聚集/聚簇索引。

为什么推荐InnoDB表用整型自增主键?

        如果没有主键的话,会自己默认选择一列没有相同内容的列作为主键。如果选不到的话就会建立一个隐藏列来作为自增主键管理整个表数据。如果自己建立好整形自增主键会减少mysql一些工作。

        自增主键会让mysql在底层不需要再做排序,节省性能,如果不是自增得话,插入到B+Tree树中还需要先排序再插入到节点中,浪费性能。

        以上是个人对于mysql索引的理解,如有不足,请多多指教!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值