mysql——Innodb行记录格式Compact

mysql——Innodb行记录格式Compact

前言

最近会一直研究mysql,主要参照书籍《MySQL技术内幕:InnoDB存储引擎》,原因是自己的sql能力实在太过于薄弱,甚至于连建表语句都要百度,所以决心花一个月研究mysql,环境是mysql5.5(不支持optimizer_trace)

Innodb主键

Innodb要求每张表都必须有主键,如果我们显示定义主键,那么就是用这个,否则它会进行如下两步操作
1:如果有 某一列是 非空唯一索引,该列成为主键,这是书籍中的话,可是笔者就抱着打破砂锅问到底的态度去验证了一番,发现还有一个限制条件,就是该列必须是int(tinyint,smallint,bigint也行)
2:不符合上述条件,生成一个6字节大小的DB_ROW_ID指针作为主键

第一点的验证截图如下
age是 not null, unique key , int
在这里插入图片描述在这里插入图片描述
而当age的这三个条件任意一个不满足的情况下
在这里插入图片描述
对于第二点这种方式证明不了,_rowid只能查到第一点这种情况

第二种情况的证明如下:

先容许我说明一下innodb_file_per_table
innodb_file_per_table = off 的意思是 ibd的数据文件都统一保存到ibdata1文件中,我的路径是D:\lry\install\mysql\ibdata1
innodb_file_per_table = on 的意思是ibd文件会根据每一个表独立保存,例如我开始该选项后数据保存在C:\ProgramData\MySQL\MySQL Server 5.5\data\lry\t1.ibd(其中ProgramData是隐藏文件夹)

我再啰嗦两句
frm文件是框架文件,表结构之类的信息
ibd文件是innodb引擎的数据及索引数据
myi文件是myisam的索引数据
myd是myisam的数据

由于我是5.5版本,默认不开启,可以用命令查看是否开启show variables like ‘%per_table%’
windows下开启该选项的方式:
进入 C:\Program Files\MySQL\MySQL Server 5.5\my.ini
最后一行添加如下
innodb_file_per_table=1 重启电脑即可,但是要记住,你之前所建立的表不会生成ibd文件,他不会帮你从ibdata1挪到ibd文件,所以要测试这个东西还得重新建表。

到此为止,innodb_file_per_table 就说完了,现在我唯一想做的事情就是打开t1.ibd文件找到DB_ROW_ID,看看是否真的帮我们生成了主键。
我用ultraEdit软件打开t1.ibd文件,和我想象的不一样,然后我又按照书籍的方式去创建mytest表

create table mytest (
  t1 varchar(10),
	t2 varchar(10),
  t3 char(10),
	t4 varchar(10)
)engine = Innodb  charset =latin1 row_format = compact

insert into mytest values ('a','bb','bb','ccc');
insert into mytest values ('d','ee','ee','fff');
insert into mytest values ('d',NULL,NULL,'fff');

得到如下结果
在这里插入图片描述
完全分析不了,用linux 的 hexdump -C -v mytest.ibd > my 生成的文件也很乱,不知道原因,这里就直接分析书籍上的吧

在这里插入图片描述

在分析上图之前,我得把compact行格式说清楚,不然没法分析

compact行记录格式

在这里插入图片描述

分析那个绿绿的图
supremum这个是上确界的意思,提示我们从0000c078,即 03(后面是02 01)开始分析
分析第一行数据a,bb,bb(定长10),ccc
03 02 01代表这行数据的变长字段的长度列表(逆序数的,ccc长度3,bb长度2,a长度1)
00 第一行没有null值 (但是像第三行数据,d,null,null,fff ,这个null标志位是06,00000110,就是把null的位置为1)
00 00 10 00 2c 记录头信息
00 00 00 2b 68 00 这个就是row_id了
00 00 00 00 06 05 tran_id
80 00 00 00 32 01 10 roll_pointer
61 就是a
62 62 就是bb
62 62 20 20 20 20 20 20 20 20 就是bb,用空格补全为10
63 63 63 就是ccc

第一行数据就分析完了,另两行也可以分析出来,这里不再赘述

总结

起初我只是想证明innodb确实帮我们生成了row_id,却没想到牵连出这么多东西,真的是才疏学浅了,这篇算是一篇刨根问底的文章了,作为技术人员的巅峰就是要有这样的精神,但我有时候也很懒,我其实一直在犹豫到底要不要写一个mysql专题,有10来天了吧,浑浑噩噩的,总感觉学完了不写一点东西出来,感觉没学一样,所以还是最终感谢自己,克服了懒惰,mysql专题会一直更新,预计耗时一个月,大概7~8篇博文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 确实,MySQL的varchar类型在InnoDB存储引擎中的存储结构比较复杂。在InnoDB中,每个记录都被存储为一个B+树节点,每个节点都有一个固定大小的页,通常为16KB。 当一个varchar类型的列被插入到InnoDB表中时,它会被拆分成两个部分:一个是实际的数据,另一个是长度信息。长度信息会被存储在记录头中,而实际的数据会被存储在记录的数据页中。 在InnoDB中,如果一个varchar类型的列的长度小于等于768个字节,那么它会被存储在记录的数据页中。如果一个varchar类型的列的长度超过了768个字节,那么它会被存储在单独的页中,并且在记录中只存储一个指向这个页的指针。 此外,由于InnoDB使用了级锁定,每个记录都需要存储一个事务ID,用于实现MVCC(多版本并发控制)。因此,在InnoDB中,每个记录头还需要存储一个6字节的事务ID和一个2字节的回滚指针。 综上所述,当使用varchar类型时,需要注意其实际数据的长度和存储引擎的存储结构,以便更好地设计表结构和查询语句。 ### 回答2: MySQL的varchar存储结构确实是相当深奥的。在InnoDB存储引擎中,varchar类型的数据存储在表的记录中,其存储结构会影响数据写入、存储空间占用和查询性能。 首先,varchar类型的数据在记录中是以变长字符串的形式进存储的。这意味着,varchar字段占用的存储空间与其实际存储的数据长度相关,而不是固定的。相比之下,固定长度的数据类型(如char)在存储时会占用固定的存储空间,无论实际数据的长度是多少。 其次,varchar类型的数据在记录中的存储格式是由一个表示长度的字节和真实字符串数据构成的。这个长度字段用于指示存储的实际数据的长度,使得数据库可以根据需要动态地分配存储空间,从而节省了存储空间。 此外,在InnoDB存储引擎中,varchar字段的数据存储在页内部的某个位置,而不是直接存储在页上。这是由于InnoDB采用了B+树的数据结构来组织数据,为了节省存储空间和提高数据访问效率,varchar字段的数据会被存储在叶子节点中。这样一来,在查询时可以更快地遍历和定位数据,提高查询性能。 综上所述,MySQL的varchar存储结构的深度体现在其变长存储方式、长度字段和数据存储位置等方面。了解和理解这些存储结构对于正确使用varchar类型的字段、优化存储空间和提高查询性能都是非常重要的。 ### 回答3: MySQL的varchar存储结构在InnoDB引擎中确实是一个很深入的话题。InnoDB引擎是MySQL的默认引擎,它采用了B+树索引来存储数据。在InnoDB记录存储结构中,varchar类型字段经过了一系列处理。 首先,InnoDB将每个记录分为固定长度部分和变长长度部分。varchar字段属于变长长度部分。对于varchar字段,MySQL会额外存储一个指针,指向数据存储区域。 其次,在实际存储varchar字段值时,InnoDB会使用两种方式。对于较短的varchar字段值,会直接将其存储在记录的数据域中。这样做的好处是可以减少额外的存储开销。 而对于较长的varchar字段值,InnoDB会将其存储在一个称为“Overflow Page”的额外存储空间中。Overflow Page的指针存储在记录的数据域中。Overflow Page与主记录有一个单独的物理连接。 另外,需要注意的是,在InnoDB中,varchar字段的长度是可变的,存储的最大长度由定义时的最大长度决定。这与char字段是不同的,char字段的长度是固定的。 总之,MySQL的varchar存储结构在InnoDB引擎中是相对复杂的。它采用了不同的存储方式来处理不同长度的字段值,既保证了数据的存储效率,又满足了灵活性的要求。对于开发人员来说,了解varchar存储结构对于正确使用和优化数据库非常重要。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值