InnoDB存储引擎,你可能还不知道的底层。

一 概述

上一篇我们了解了mysql的结构,这篇,叶子就和大家好好聊聊mysql最具特色的功能,存储引擎。
如果还不了解mysql的结构,可以看看叶子的上一篇文章。
浅谈MySQL体系,这下总该懂了吧!

mysql适用于多种复杂的业务场景,不管是增多查少,还是增少查多,亦或者是增多查多,他统统都能满足,那它为什么能做到这一步呢,这就离不开他的存储引擎了。
这里,我们暂时只说5.5版本后默认支持的存储引擎InnoDB。

二 InnoDB是什么?

对各位小伙伴来说,InnoDB存储引擎应该是一点都不陌生的,在MySql 5.5版本后,InnoDB存储引擎就是MySql默认的存储引擎。
它具备以下的特点:

DML操作遵循ACID模型,支持事务。
支持行级锁,提高并发访问性能。
支持外键约束,保证数据的完整性和正确性。
它存储在磁盘上的文件xx.ibd,xx代表的是表名,ibd则是文件后缀,InnoDB引擎每张表都会对应一个表空间文件,存储表的结构,数据和索引。
可以通过查看innodb_file_per_table参数,默认是开启的,即使用InnoDB存储引擎创建的表,默认都会生成对应的ibd文件。

show variables like ‘innodb_file_per_table’;

在这里插入图片描述
每一张表都有一个对应的ibd文件,我们直接打开mysql的数据存放目录就可以看到。

在这里插入图片描述

ibd文件不仅存放表结构,数据,还会存放该表对应的索引信息,并且这个文件是基于二进制存储的,不能直接打开,我们可以使用mysql提供的一个指令ibd2sdi,就可以从ibd文件中提取sdi的信息,sdi数据字典信息就存放在这个文件中。

在这里插入图片描述

InnoDB的逻辑存储结构

在这里插入图片描述

在InnoDB存储引擎中,他的内存区域包含表空间,段,区,页,行,如下图所示

      表空间 : InnoDB存储引擎逻辑结构的最高层,ibd文件其实就是表空间文件,在表空间中可以包含多个段。
      
       段 : 表空间是由各个段组成的, 常见的段有数据段、索引段、回滚段等。InnoDB中对于段的管理,都是引擎自身完成,不需要人为对其控制,一个段中包含多个区。
       
       区 : 区是表空间的单元结构,每个区的大小为1M。默认情况下, InnoDB存储引擎页大小为16K, 即一个区中一共有64个连续的页。

       页 : 页是组成区的最小单元,页也是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。为了保证页的连续性,InnoDB 存储引擎每次从磁盘申请 4-5 个区。

       行 : InnoDB 存储引擎是面向行的,也就是说数据是按行进行存放的。

索引就是在存储引擎层实现的,不同的存储引擎有不同的索引结构,常见的有B+Tree索引,Hash索引,以及一些不常见的R-Tree索引(空间索引,是MyISAM中的一种特殊索引,用于地理空间数据,用的较少)

下面,我们要说的,就是InoDB引擎的底层B+Tree索引。

在这里插入图片描述

如图所示,这里我采用的五阶,也就是说每个节点最大保存四个Key值,五个指针,超过了,树就会进行分裂,中间元素向上,左小右大,并且,在B+Tree中,非叶子结点不会存放数据,具体的数据都是存放在叶子节点的。

在这里插入图片描述

有兴趣的小伙伴可以自己试一下,网址:

https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

那为什么说B+Tree高效呢,我们来做一道题,一页存储16kb数据,假设一行数据1kb,主键索引为bigint,占据8个字节,指针占据6个字节,这样计算下来

     n * 8+(n+1)*6=16*1024

     n=1170

也就是说,树的高度如果为2,那么就是1170*16约等于一万八千多条记录,而到了第三层,则是在二层树的基础上继续乘上1170,数据可达到两千两百多万条,三层的B+树,三次磁盘IO,存储千万条数据,这已经能满足日常大部分业务需求了。

当然,这样计算只是粗略计算,数据页还会存放一些固定的信息,页头,页尾,页目录之类的,大概也能占据1k样子。

最后再说一点,有的小伙伴可能已经想到了,这是基于行数据在1kb或者1kb以下算出来的,如果说行数据过大超过了1kb,甚至是达到了10kb,那三层的B+tree还能存储这么多数据吗,如果能存的话,为什么能存,不能存的话,又该怎么办呢,这些我后续专门写一篇说明吧!

实际上 MySql使用的,并不是原本的B+Tree,而是对B+Tree进行了优化,在原有结构的基础上,叶子结点增加了链表指针,提高了区间访问的性能,利于排序,方便范围查找。

总结

ok,这篇我们了解了InnoDB引擎是干什么用的,以及它的内存模型,它的底层结构B+树,知道了B+树为什么能存储这么多的数据,希望小伙伴们都能所有收获,最后的最后,如果大家喜欢的话,看完记得点赞哦。
欢迎关注叶子的公众号【一叶知求】 更多技术分享都在上面哦!

每日一题:

请用java语言实现一个二叉查找树,小伙伴们可以好好思考下,叶子这边给出一个参考,抛砖引玉。

参考答案:

**
 *
 * @author yiyezhiqiu
 *
* */
    public int halfSearch(int[] nums, int target) {
        if (nums == null) return -1;
        //最左侧数字下标
        int left = 0;
        //最右侧数字下标
        int right = nums.length;
        //左边小于右边,则循环一直继续,直到左边等于或者大于右边
        while (left < right) {
            //初次查找从一半开始
            int mid = left + ((right - left) >> 1);
             /*
            * 目标值小于中间值,则中间值赋给右侧数据,此时数据区间则是从开始到原本数据的中间值,
            * 反之,则赋值给左侧值,新数据区间则从原本的中间值到最右侧的值
            * */
            if (target <= nums[mid]) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        if (left < nums.length && nums[left] == target) {
            return left;
        };
        return -1;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值