本报讯 柬埔寨王宫事务部9月24日发布通告称,最受柬埔寨民众尊敬、爱戴的诺罗敦·莫尼列·西哈努克王太后陛下已年过花甲,目前正在北京的医院接受悉心治疗。...
2025-09-25 8
关注
“脚本之家
”,与百万开发者在一起
本文经艾小仙(id:aixiaoxianren)授权转载
如若转载请联系原公众号
在之前的文章提到过一个问题,而且网上很多文章也是这么说的,前几天有人对这个问题提出了一点不同的意见,抱着谨慎的态度做了一个测试。
问题是这样的:COMPACT格式下,NULL值列表是否一定会占用一个字节的空间?
对于这个问题,我的回答和网上很多回答是一样的,如果都是NOT NULL就不会有NULL值列表,所以不会占用,反之则会占用。
今天,就对这个问题做一个验证。
存储空间
先回顾一下之前的知识。
数据库中的一行记录在最终磁盘文件中也是以行的方式来存储的,对于InnoDB来说,有4种行存储格式: REDUNDANT 、 COMPACT 、 DYNAMIC 和 COMPRESSED 。
InnoDB的默认行存储格式是 COMPACT ,存储格式如下所示,虚线部分代表可能不一定会存在。
变长字段长度列表:有多个字段则以逆序存储,我们只有一个字段所有不考虑那么多,存储格式是16进制,如果没有变长字段就不需要这一部分了。
NULL值列表:用来存储我们记录中值为NULL的情况,如果存在多个NULL值那么也是逆序存储,并且必须是8bit的整数倍,如果不够8bit,则高位补0。1代表是NULL,0代表不是NULL。如果都是NOT NULL那么这个就存在了,每多8个NULL会多占用一个字节的空间。
ROW_ID:一行记录的唯一标志,没有指定主键的时候自动生成的ROW_ID作为主键。
TRX_ID:事务ID。
ROLL_PRT:回滚指针。
最后就是每列的值。
为了说明清楚这个存储格式的问题,我弄张表来测试,这张表只有 c1 字段是NOT NULL,其他都是可以为NULL的。
展开全文
可变字段长度列表: c1 和 c3 字段值长度分别为1和2,所以长度转换为16进制是 0x01 0x02 ,逆序之后就是 0x02 0x01 。
NULL值列表:因为存在允许为NULL的列,所以 c2,c3,c4 分别为010,逆序之后还是一样,同时高位补0满8位,结果是 00000010 。
其他字段我们暂时不管他,最后第一条记录的结果就是,当然这里我们就不考虑编码之后的结果了。
这样就是一个完整的数据行数据的格式,反之,如果我们把所有字段都设置为NOT NULL,并且插入一条数据 a,bb,ccc,dddd 的话,存储格式应该这样:
测试
这里存在一点点小问题,首先我看到了阿里的数据库月报中的测试和描述。
从这段代码看出之前的猜想,也就是并不是Null标志位只固定占用1个字节==,而是以8为单位,满8个null字段就多1个字节,不满8个也占用1个字节,高位用0补齐
从这段代码看出之前的猜想,也就是并不是Null标志位只固定占用1个字节==,而是以8为单位,满8个null字段就多1个字节,不满8个也占用1个字节,高位用0补齐
他的意思是无论如何都会占用一个字节,但是看了他的测试,发现他的表是允许NULL的,所以他的这个测试无法说明我们要验证的问题。
按照网上大佬给出的方案,创建表,然后插入测试数据,数据库中存在NULL值。
CREATETABLEtest( c1 VARCHAR( 32),
c2 VARCHAR( 32),
c3 VARCHAR( 32),
c4 VARCHAR( 32) ) ENGINE= INNODBrow_format = compact;
使用命令 SHOW VARIABLES LIKE 'datadir' 找到 ibd 文件位置。
使用命令转换 ibd 文件为 txt 文件。
hexdump -C -v test.ibd > /Users/irving/test-null.txt
打开文件找到 supremum 部分。
不用看那么多,就看一部分:
03 02 02 01 是上面说的变长字段长度列表,以为我们有4个字段,所以4个字节。
00 就是NULL标志位
00 00 10 00 25 是数据头5个字节
03 02 02 01 是上面说的变长字段长度列表,以为我们有4个字段,所以4个字节。
00 就是NULL标志位
00 00 10 00 25 是数据头5个字节
这个肯定没有问题,然后再次创建一张表,这时候字段都是NOT NULL,然后再次执行命令。
CREATETABLEtest( c1 VARCHAR( 32) NOTNULL,
c2 VARCHAR( 32) NOTNULL,
c3 VARCHAR( 32) NOTNULL,
c4 VARCHAR( 32) NOTNULL) ENGINE= INNODBrow_format = compact;
拿到另外一个 ibd 文件。
对比其实很清楚能发现问题,这时候已经没有了NULL值列表的标志位了。
SO,这个测试结果证明,如果存在任意NULL值,NULL值列表至少占用一个字节的空间,以后每多8个NULL值多占用一个字节,如果都是NOT NULL,则不会存在NULL值列表标记,不占用空间。
巨人的肩膀:
/
/
<END>
程序员专属卫衣
商品直购链接
【☝?点击查看更多详情】
专属定制,程序员秒懂的极客卫衣!
为什么阿里巴巴禁止数据库中做多表join?
美团三面:一直追问我, MySQL 幻读被彻底解决了吗?
什么?你还不会安装MySQL
Mysql的索引为什么使用B+树而不使用跳表?
Office 2019/2021专业增强版,正版终身授权!
相关文章
本报讯 柬埔寨王宫事务部9月24日发布通告称,最受柬埔寨民众尊敬、爱戴的诺罗敦·莫尼列·西哈努克王太后陛下已年过花甲,目前正在北京的医院接受悉心治疗。...
2025-09-25 8
自从特鲁多政府在美国的怂恿下,对中国产电动汽车、钢铁和铝产品加征高额关税以来,加拿大与中国的关系就如同滑下了拼命向下的轨道。中国这一举动无疑是给加拿大...
2025-09-25 7
据报道,近年来的中美博弈已不仅仅体现在贸易战、科技封锁和军事对抗等领域,金融和资本市场的较量同样成为了全球关注的焦点。中国连续大规模减持美国国债,特别...
2025-09-25 7
近日,四川成都一自行车车迷赛中发生选手集体摔车事故,一名年轻男选手疑似膝盖伤情严重,被传“膝盖骨没了”,引发众多网友热议。日前,成都市体育局回应新黄河...
2025-09-25 5
【环球网快讯】据《以色列时报》25日最新消息,以色列军方宣布,一名以色列国防军士兵在加沙城遭巴勒斯坦伊斯兰抵抗运动(哈马斯)狙击手袭击身亡。 报道称,...
2025-09-25 7
花费不菲入住五星级酒店 半夜却无奈躲在阳台 究竟发生了什么? 近日 30岁的孙先生反映 夫妻俩入住上海星河湾酒店后 自己眼角膜受伤,视物不清 妻子肺部...
2025-09-25 5
每经编辑|何小桃 据新黄河9月24日报道,记者近日获悉,浙江省绍兴市轨道交通2号线9月13日晚曾发生一起地铁列车撞上保洁员致多人伤亡的安全事故。 多名...
2025-09-25 5
资料图:上海绿捷 本文综合上观新闻、正观新闻、采招网、21世纪经济报道等 昨天(9月23日)深夜,针对公众关注的“臭味学生餐”事件,上海官方发布通报称...
2025-09-25 6
发表评论