首页 > 其他分享 >【innodb阅读笔记】之 索引组织表

【innodb阅读笔记】之 索引组织表

时间:2024-12-05 14:31:31浏览次数:8  
标签:level MySQL 笔记 索引 innodb offset type page

一、组织索引表主键规则

        在Innodb存储引擎中,表都是根据主键索引的顺序组织存放的,这种存放方式的表称为索引组织表,在innodb存储引擎表中,每个表都有一个主键,如果在创建表的时候没有显示的定义主键,则innodb会按如下方式选择或创建主键:

        1. 首先判断表是否有非空唯一索引,如果有,则该列为主键,若过有多个唯一非空索引,则按照定义顺序,选择第一个为主键

        2. 如果不符合上述条件,innodb存储引擎自动创建一个6字节大小的指针

创建数据库 但是没有指定主,也没有创建唯一索引
CREATE TABLE z (
 a INT NOT NULL,
 b INT NULL,
 c INT NOT NULL,
 d INT NOT NULL
);

# 插入数据
insert into z select 1, 2, 3, 4

# 查询主键报错,证明是自动生成的,
# _rowid 可以查询非自动生成的,同时不是联合索引的主键
mysql> SELECT _rowid FROM z ;
ERROR 1054 (42S22): Unknown column '_rowid' in 'field list'


# 创建唯一索引 d的顺序在c的前面,b不是非空索引
mysql> CREATE TABLE z (
    ->  a INT NOT NULL,
    ->  b INT NULL,
    ->  c INT NOT NULL,
    ->  d INT NOT NULL,
    ->  UNIQUE KEY(b), UNIQUE KEY(d), UNIQUE KEY(c)
    -> );
Query OK, 0 rows affected (0.03 sec)


# 插入数据
insert into z select 1, 2, 3, 4;
insert into z select 5, 6, 7, 8;
insert into z select 9, 10, 11, 12;

# 发现选择第一个定义的非空唯一索引为数据库主键
mysql> SELECT a,b,c,d,_rowid FROM z ;
+---+------+----+----+--------+
| a | b    | c  | d  | _rowid |
+---+------+----+----+--------+
| 1 |    2 |  3 |  4 |      4 |
| 5 |    6 |  7 |  8 |      8 |
| 9 |   10 | 11 | 12 |     12 |
+---+------+----+----+--------+
3 rows in set (0.00 sec)

二、innodb逻辑存储结构

        从Innodb存储引擎的逻辑存储结构看,所有数据都被逻辑的存放在一个空间中,称为表空间。表空间又由段、区、页组成,存储结构大致如下:

1. 表空间

        表空间可以看做是innodb存储引擎逻辑结构的最高层,所有数据都存放在表空间中,如果启用了 innodb_file_per_table 的参数,则每张表存放自己独立的数据,索引,插入缓存bitMap页,其他类的数据,如回滚信息、插入缓存索引页、系统事务信息等一些数据,还存放在共享表空间ibdata1 中,即使启用了 innodb_file_per_table 参数,共享表空间还是会不断的增加其大小,现在,我们做一个实验:

# 开启独立表空间 
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)


# 共享空间大小为 12MB, 


# 使用刚才创建好的表结构
CREATE TABLE z (
 a INT NOT NULL,
 b INT NULL,
 c INT NOT NULL,
 d INT NOT NULL,
 UNIQUE KEY(b), UNIQUE KEY(d), UNIQUE KEY(c)
);

# 开启显示提交事务
begin;

# 修改数据,可以添加数据 数据越多,效果越明显
mysql> update z set a = a + 1;
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7  Changed: 7  Warnings: 0


# 再重复执行了1000次后,共享空间大小为 12.5MB, 证明,事务等数据信息存放在共享表空间中

# 有人或许会问,当事务回滚以后,表空间会恢复之前的大小吗?
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

# 回滚事务后,我们发现共享表空间没有变小,所以不会进行回收,
# 但是下次会判断这些数据是否可以被覆盖,如果不需要,进行标记,以提供下次使用,



# 下面是innodb存储引擎大佬写的一个插件,通过这个插件,我们可以查看表空间页的具体信息
D:\readBooks\mysql\david-mysql-tools-master\py_innodb_page_type>py_innodb_page_info.py -v D:/readBooks/mysql/t.ibd
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0000>
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 6:
Freshly Allocated Page: 2
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 1
File Segment inode: 1

2. 段

        上图显示了表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等。innodb存储引擎表是索引组织的,所以,索引既数据,数据既索引。那么数据段既 B+ 树的叶子节点,索引段既为 B+ 树的非叶子节点。

        在innodb存储引擎中,对段的管理都是由索引自身所完成的,DBA不能也没有必要对其进行控制。

3. 区

        区是由连续的页组成的,在任何情况下每个区的大小都为 1MB,为了保证区中页的连续性,Innodb存储引擎一次从磁盘申请 4 到 5 个区,在默认情况下,每个页的大小为16KB,一个区一共有 64 个连续的页。

        这有一个问题,当我们创建表的时候,表的大小默认为 96 KB,区中是64个连续的页,创建的表最小也应该是1MB才对? 这是因为,每个段在开始的时候,先用32个页大小的碎片页来存放数据,在使用完这些页之后才是64个连续页的申请,这样做的目的是,对于一些小表,可以在开始的时候申请比较少的空间,节省空间,防止空间浪费。

# 创建数据表
mysql> create table t1 (
    -> col1 int not null auto_increment,
    -> col2 varchar(7000),
    -> primary key(col1)
    -> ) engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)

# 数据文件大小
D:\ProgramData\MySQL\MySQL Server 5.7\MySQL_data\innodb_test>dir
2024/12/05  10:58  98,304 t1.ibd

# 插入数据
mysql> insert t1 select null, repeat('a', 7000);
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql>
mysql> insert t1 select null, repeat('a', 7000);
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

# 通过 py_innodb_page_info 查看表空间情况
D:\ProgramData\MySQL\py_innodb_page_type>py_innodb_page_info.py -v    
"D:/ProgramData/MySQL/MySQL Server 5.7/MySQL_data/innodb_test/t1.ibd"
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0000>
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 6:
Freshly Allocated Page: 2
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 1
File Segment inode: 1

# page offset 00000003 这个表示的是数据页,page level 等于0, 表示叶子节点,
# 因为现在所有数据都处于一个页当中,所以没有非叶子节点


# 我们再插入 2 条数据,再次查询表空间情况
D:\ProgramData\MySQL\py_innodb_page_type>py_innodb_page_info.py -v 
"D:/ProgramData/MySQL/MySQL Server 5.7/MySQL_data/innodb_test/t1.ibd"
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0001>
page offset 00000004, page type <B-tree Node>, page level <0000>
page offset 00000005, page type <B-tree Node>, page level <0000>
Total number of page: 6:
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 3
File Segment inode: 1
# 此时,我们发现 产生了两个 page level 等于 0 的叶子节点,
# 同时产生了一个 page level 等于 1 的非叶子节点

# 我们再插入60次数据,当前数据库数据保存为63条
mysql> select count(1) from t1;
+----------+
| count(1) |
+----------+
|       63 |
+----------+
1 row in set (0.00 sec)

# 可以看到 我们在插入63条数据的时候,数据库的大小还是小于 1MB
D:\ProgramData\MySQL\MySQL Server 5.7\MySQL_data\innodb_test>dir
2024/12/05  11:13           606,208 t1.ibd

# 通过查看表空间情况,可以观察到 b-tree node页,一共 33个,
# 除去一个非叶子节点,一共32个非叶子节点,也就是说已经有32个碎片页了
D:\ProgramData\MySQL\py_innodb_page_type>py_innodb_page_info.py -v 
"D:/ProgramData/MySQL/MySQL Server 5.7/MySQL_data/innodb_test/t1.ibd"
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0001>
page offset 00000004, page type <B-tree Node>, page level <0000>
page offset 00000005, page type <B-tree Node>, page level <0000>
page offset 00000006, page type <B-tree Node>, page level <0000>
page offset 00000007, page type <B-tree Node>, page level <0000>
page offset 00000008, page type <B-tree Node>, page level <0000>
page offset 00000009, page type <B-tree Node>, page level <0000>
page offset 0000000a, page type <B-tree Node>, page level <0000>
page offset 0000000b, page type <B-tree Node>, page level <0000>
page offset 0000000c, page type <B-tree Node>, page level <0000>
page offset 0000000d, page type <B-tree Node>, page level <0000>
page offset 0000000e, page type <B-tree Node>, page level <0000>
page offset 0000000f, page type <B-tree Node>, page level <0000>
page offset 00000010, page type <B-tree Node>, page level <0000>
page offset 00000011, page type <B-tree Node>, page level <0000>
page offset 00000012, page type <B-tree Node>, page level <0000>
page offset 00000013, page type <B-tree Node>, page level <0000>
page offset 00000014, page type <B-tree Node>, page level <0000>
page offset 00000015, page type <B-tree Node>, page level <0000>
page offset 00000016, page type <B-tree Node>, page level <0000>
page offset 00000017, page type <B-tree Node>, page level <0000>
page offset 00000018, page type <B-tree Node>, page level <0000>
page offset 00000019, page type <B-tree Node>, page level <0000>
page offset 0000001a, page type <B-tree Node>, page level <0000>
page offset 0000001b, page type <B-tree Node>, page level <0000>
page offset 0000001c, page type <B-tree Node>, page level <0000>
page offset 0000001d, page type <B-tree Node>, page level <0000>
page offset 0000001e, page type <B-tree Node>, page level <0000>
page offset 0000001f, page type <B-tree Node>, page level <0000>
page offset 00000020, page type <B-tree Node>, page level <0000>
page offset 00000021, page type <B-tree Node>, page level <0000>
page offset 00000022, page type <B-tree Node>, page level <0000>
page offset 00000023, page type <B-tree Node>, page level <0000>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 37:
Freshly Allocated Page: 1
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 33
File Segment inode: 1

# 现在我们再插入一条数据,发现表空间大小变为 2MB
# 因为已经用完32个碎片页,新的页区会采用区的方式进行空间的申请,
D:\ProgramData\MySQL\MySQL Server 5.7\MySQL_data\innodb_test>dir
2024/12/05  11:19  2,097,152 t1.ibd

# 此时 在查看表空间情况,会出现有很多空闲页
Freshly Allocated Page: 91

4. 页

        在innodb存储引擎中,页是innodb磁盘管理的最小单位,默认每个页的大小为16KB,通过参数 innodb_page_size 可以将页的大小设置为 4KB、8KB、16KB,若设置完成,每个页大小都为 innodb_page_size,不可再次对其发生更改。

        在Innodb存储引擎中,常见的页有:数据页、undo页、系统页、事务数据页、插入缓存位图页、插入缓存空闲列表页、未压缩的二进制大数据页、压缩的二进制数据页。

# 页默认大小
mysql> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set, 1 warning (0.00 sec)

5. 行

        Innodb存储引擎是面向列。也就是说数据时按照行进行存放的,每个页存放的行记录是有硬性定义的,最多存放 16KB / 2 - 200 行的记录,既7992行记录。

标签:level,MySQL,笔记,索引,innodb,offset,type,page
From: https://blog.csdn.net/weixin_43262384/article/details/144256401

相关文章

  • WPF笔记10——Visibility.Hidden和Visibility.Collapsed
    在WPF中,Visibility.Hidden和Visibility.Collapsed在某些情况下看起来运行效果相似,但实际上有一些区别:1、布局影响Visibility.Collapsed:当一个元素的Visibility属性被设置为Visibility.Collapsed时,该元素在布局过程中会被完全忽略。就好像这个元素不存在一样,它不会占据任......
  • 并查集学习笔记
    一、例题引入洛谷P3367【模板】并查集题目描述如题,现在有一个并查集,你需要完成合并和查询操作。输入格式第一行包含两个整数$N,M$,表示共有$N$个元素和$M$个操作。接下来$M$行,每行包含三个整数$Z_i,X_i,Y_i$。当$Z_i=1$时,将$X_i$与$Y_i$所在的集合合并。......
  • WPF笔记9——设置应用程序单实例运行
    设置WPF应用程序单实例运行**方式1:**///<summary>///InteractionlogicforApp.xaml///</summary>publicpartialclassApp:Application{///<summary>///程序启动///</summary>///<pa......
  • 【学习笔记总结】华为云:应用上云后的安全规划及设计
    一、背景和问题        数字化时代,随着信息技术的飞速发展,企业和各类组织纷纷将自身的应用程序迁移至云端。云计算凭借其诸多优势,如成本效益、可扩展性、灵活性以及便捷的资源共享等,已然成为了现代业务运营的重要支撑。    今年,我所在企业也将IT系统全面迁移......
  • C语言笔记--文件操作
    为什么使用文件使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。什么是文件磁盘上的文件是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。程序文件包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),......
  • OSG开发笔记(三十七):OSG基于windows平台msvc2017x64编译器官方稳定版本OSG3.4.1搭建环境
    前言  自行编译的osg版本插件比较多,如果对版本没有特定要求,但是对环境编译器有特定要求,可以反向融合编译器符合要求的osg版本。 OSG下载过程  osg官网:http://www.osgchina.org        由于我们不使用osgQt模块,下载了也无所谓,反正不用,这里是osg3.6.4......
  • 索引的创建原则、索引失效的场景
    索引创建的原则有哪些?在项目中主要用到主键索引、唯一索引、根据业务创建的索引(复合索引)*针对数据量较大,而且查询比较频繁的表建立索引(单表超过10w条数据(增加用户体验))*针对常作为查询条件(where)、排序(orderby)、分组(groupby)操作做的字段建立索引尽量选择区分度高的字......
  • 数学建模论文写作技巧!保姆级教程!(清风写作课笔记)
    文章目录目录论文标题摘要(1000字左右)摘要开头段(必要)摘要中间段(最重要)摘要结尾段摘要中常见的废话关键词一、问题重述二、问题分析三、模型假设四、符号说明模型的建立与求解(正文里最重要)六、模型的分析与检验七、模型的评价、改进与推广参考文献注意事项附录目录......
  • 数据传输(小迪网络安全笔记~
    附:完整笔记目录~ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!4.1数据传输引子:上一章主要介绍了无回显&不出网,概念、影响、解决方式等。本篇则对网络通信中的数据传输进行介绍,包括数据传输格式、不同类型数据对测试者造成的影响等。概述为实现用户与服务器间的......
  • 编码加密(小迪网络安全笔记~
    附:完整笔记目录~ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!4.2编码加密引子:上一篇主要对常见数据传输类型做了总结,而本篇则对数据常见的编码&加密方式进行总结。概述:编码&加密除了对后端敏感数据的保护,其在前端数据传输时往往也会被应用到。根据上一篇的学......