【Mysql】InnoDb行格式、数据页结构以及索引底层原理分析


在这里插入图片描述

我们用JDBC 等连接MySQL 其实就是,jdbc是客户端来连接MySQL服务器。

Mysql服务器中负责对表中数据的读取和写入工作的部分是存储引擎,支持的存储引擎就是倒数第二行的innobd、memory、myisam等。
存储引擎的上一层是 处理数据的, 下一层是真的文件系统。

InnoDB

innodb_space 是可以查看 innodb具体怎么存数据的工具
我们要讲的是innodb,它是将表中的数据存储到磁盘上的存储引擎。

InnoDB存储引擎不需要一条一条的把记录从磁盘上读出来,InnoDB采取的方式是:

  • 将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位
  • InnoDB中页的大小一般为 16 KB
    也就是说,当需要从磁盘中读数据时每一次最少将从磁盘中读取16KB的内容到内存中,每一次最少也会把内存中的16KB内容写到磁盘中

InnoDB数据页结构

每次InnoDB拿的页即数据页,为16kb,这16kb大小的存储空间可以被划分为多个部分,示意图如下:
在这里插入图片描述

  • 名称中文名占用空间简单描述
    File Header文件头部38字节页的一些通用信息
    Page Header页面头部56字节数据页专有的一些信息
    Infimum + Supremum最小记录和最大记录26字节两个虚拟的行记录
    User Records用户记录不确定实际存储的行记录内容
    Free Space空闲空间不确定页中尚未使用的空间
    Page Directory页面目录不确定页中的某些记录的相对位置
    File Trailer文件尾部8字节校验页是否完整

InnoDB 行格式

我们平时是以记录为单位向表中插入数据的,这些记录在磁盘上的存放方式被称为行格式。

行格式分别是Compact、Redundant、Dynamic和Compressed行格式

Compact

在这里插入图片描述

  • 记录的真实数据:
    记录的真实数据除了我们自己定义的列的数据外,还加了隐藏列:

    列名是否必须占用空间描述
    row_id6字节行id,唯一标识一条记录
    transaction_id6字节事务id
    roll_pointer7字节回滚指针

    InnoDB对主键的生成策略
    优先使用用户自定义主键作为主键,如果没定义,则选取一个unique键作为主键,如果没有定义unique键,则会为表默认添加一个row_id 作为主键.
    行溢出
    一页只能存16kb, 而一个varchar的类型的列最多就可以存65533个字节,这样就会造成一页存不了一条记录.
    在Compact和Reduntant格式中, 记录真实数据数据处只会存储该列的一部分数据,把剩余的数据分散存储在其他几个页中,记录指向这些页的地址.

  • 行格式除了记录真实数据外,还会记录额外信息:

    • 变长字段长度列表
      比如我们有varchar[varchar是可变长度的,所以占用空间不确定] ,这里就会记录这个varchar对应的真实的长度

    • NULL值列表
      把这行数据里是null的都记录下来. 具体就是将每个允许存储null的列对应一个二进制位,二进制位位1时,代表该列的值位null.

    • 记录头信息
      记录头信息用于描述记录,由固定的5个字节组成,即40个二进制位,不同的位代表不同的意思:
      在这里插入图片描述

Dynamic和Compressed

Dynamic和Compressed类似于行格式, 只是处理行溢出不同,他们不会在记录的真实数据处存储一部分数据,而是把所有的数据都存储到其他页面,只有在记录的真实数据处存储其他页面的地址.

Compressed行格式会采用压缩算法对页面进行压缩.

索引

B+ 树

我们把数据按下面的格式存,每个页面都按照索引列的值建立了页目录.
在这里插入图片描述
其实就是B+树:
在这里插入图片描述

上面的是模拟,InnoDB的做法:
当第一页满了以后,会把第一页复制一份,把原来的第一页作为页目录.
这样可以保证入口永远不变.
在这里插入图片描述

叶子结点存了所有排好序的数据

聚集索引和辅助索引

  • 聚集索引

    • 按照每个表的主键构造一颗B+树,同时页节点存放的是整张表的行记录数据,每一个叶子节点都被称为数据页。
    • 聚集索引是逻辑上连续不是物理连续
    • 聚集索引对于主键的排序查找和范围查找速度非常快
  • 辅助索引

    • 叶子节点并不包含记录的全部数据,每个叶子节点中的索引行中存的不是这一行数据而是主键.
      通过这个主键去找对应的行数据

真正实现的时候 会把主键也加到辅助索引的节点中,因为 辅助索引的值有可能重复,我们把主键也加进去 就不会重复了

建立索引

建立索引 其实就是选择要排序的键, 按照我们选的键 进行排序 建立新的B+树

意思是用b c d 三个列 来建立索引, 就是b的值相同 就比较c 再比较d

create index idx_t1_bcd on t1(b,c,d)

考虑索引选择性

索引的选择性 是指不重复的索引值(基数) 与表记录数的壁纸

选择性 = 基数 / 记录数

选择性的取值范围为(0, 1],选择性越高的索引价值越大。如果选择性等于1,就代表这个列的不重复值和表记录数是一样的,那么对这个列建立索引是非常合适的,如果选择性非常小,那么就代表这个列的重复值是很多的,不适合建立索引。

考虑前缀索引

比如varchar的长度很长,我们可以选取他的前几位建立索引
比如下面是算用first_name和last_name的前3位建立索引的选择性

    SELECT count(DISTINCT(concat(first_name, left(last_name, 3))))/count(*) AS Selectivity FROM employees.employees;

前缀索引的缺点: 不能用于orderby和group by 操作,也不能用于覆盖索引

索引的代价

空间上的代价

一个索引都为对应一棵B+树,树中每一个节点都是一个数据页,一个页默认会占用16KB的存储空间,所以一个索引也是会占用磁盘空间的。

时间上的代价

每次对表中的数据进行增删改操作时,都要去修改各个B+树索引

不可以使用索引进行排序或分组的几种情况

  1. asc 和desc 混用
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL的全文索引底层原理是基于倒排索引的。在MySQL中,全文索引只支持英文,如果需要对中文进全文检索,可以使用sphinx的中文版(coreseek)。 底层原理包括MySQL缓冲池、索引底层原理分裂与合并、B树的优势以及索引操作等。 MySQL缓冲池是用于管理数据的,包括数据数据管理、free链表、flush链表、哈希表以及LRU链表。 索引底层原理分为InnoDB索引和MyISAM索引InnoDB索引包括记录与索引索引、B树结构、聚簇索引以及InnoDB索引文件。而MyISAM索引包括聚簇索引VS非聚簇索引以及MyISAM索引文件。 分裂与合并是指当索引数据满了之后,需要进分裂操作,将数据分散到新的数据中,或者当数据删除时,空间过多时需要进合并操作,将数据整理到更少的中。 B树是一种常用的索引数据结构,相比于其他数据结构如AVL树、红黑树、哈希表和跳表,B树具有较好的平衡性和高效的插入、删除和查找性能,因此被广泛应用于索引中。 索引操作包括创建索引、删除索引、查看索引、全文索引和复合索引最左匹配原则等。创建索引默认主键,删除索引是指删除已经创建的索引,查看索引可以使用EXPLAIN语句来查看索引的使用情况。全文索引用于对文本内容进全文检索,而复合索引最左匹配原则是指在复合索引中,只有最左边的列被使用时索引才会生效。 综上所述,MySQL的全文索引底层原理是基于倒排索引的,具体包括MySQL缓冲池、索引底层原理分裂与合并、B树的优势以及索引操作等方面的内容。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MYSQL索引底层原理](https://blog.csdn.net/winy1986/article/details/125758304)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [详解MySQL索引底层原理](https://blog.csdn.net/Wyf_Fj/article/details/126415270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值