热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

InnoDB行记录格式(compact)

1.变长字段长度列表记录非NULL变长字段的长度列表;并且安装列的循序的逆序进行放置,一列的长度如果小于255,用一字节表示,如果长度长度大于255,则用两字节表示,一字节还是两字节


1. 变长字段长度列表        记录非NULL变长字段的长度列表; 并且安装列的循序的逆序进行放置,一列的长度如果小于255,用一字节表示,如果长度长度大于255,则用两字节表示,一字节还是两字节只对一列来讲,如果一行中既有大于255,也有小于255的,则大于255用两字节,小于255则用一字节。从分析文件的十六进制来看,如果大于255,则高字节的最高位是1.  还需要分析代码是否高位都是1,如果是,那变长的最大长度是多少? 统计每一个列中数据的长度,在统计这个信息的时候,又有多种情况,主要分定长字段和变长字段,对于定长字段,它的长度直接就是数据类型的长度,比如int类型的那就是4个字节,rowid列就是6个字节等,没有其它附加长度。对于变长字段而言,除了数据内容本身的长度外,还需要计算其数据长度的存储空间,如果字段的字义长度大于255个字节,或者字段的数据类型为BLOB的,那么需要用2个字节来存储这个字段的长度;如果定义长度小于128个字节,或者小于256个字节,但类型不是BLOB类型的,那么这个字段的数据长度用一个字节来存储,除上面2种情况之外,都用2个字节来存储
代码中的注释: rem0rec.c  rec_get_converted_size_comp_prefix() If the maximum length of a variable-length field(这个应该是表中定义的长度)        is up to 255 bytes, the actual length is always stored        in one byte. If the maximum length is more than 255        bytes, the actual length is stored in one byte for        0..127.  The length will be encoded in two bytes when        it is 128 or more, or when the field is stored externally.

从这个插入记录(例2)来看, 长度的表达不仅和字段的定义有关, 还和插入的长度有关, 当长度的定义大于255时,  长度大于127时, 就用两个字节来表示(如下面这个表的最后一个字段), 当是127时只用一个字节来表示, 当等于128时就用两个字节来表示(80 80), 第二字节的最高位都是1; 当一个字段的定义小于255时, 它的长度都用一个字节来表示, 不管大于还是小于127.
例1 create table mytest10(t1 VARCHAR(256), t2 VARCHAR(100), t3 CHAR(50), t4 VARCHAR(300)) ENGINE=INNODB CHARSET=latin1 row_format=compact;
INSERT INTO mytest10 SELECT  REPEAT('a',256), REPEAT('b', 90), REPEAT('c', 40), REPEAT('d',300);INSERT INTO mytest10 SELECT  REPEAT('e',20), REPEAT('f', 100), REPEAT('g', 40), REPEAT('h',300);INSERT INTO mytest10 SELECT  REPEAT('i',20), REPEAT('j', 100), REPEAT('k', 40), REPEAT('l',100);
INSERT INTO mytest10 SELECT  REPEAT('q',200), REPEAT('r', 100), REPEAT('s', 40), REPEAT('t',150); INSERT INTO mytest10 SELECT  REPEAT('u',128), REPEAT('v', 100), REPEAT('w', 40), REPEAT('x',127);

分析文件的长度列表如下  [上面十进制,下面十六进制] INSERT INTO mytest10 SELECT  REPEAT('a',256), REPEAT('b', 90), REPEAT('c', 40), REPEAT('d',300); 300     90   256    null标志 2c 81  5a   00 81 00
INSERT INTO mytest10 SELECT  REPEAT('e',20), REPEAT('f', 100), REPEAT('g', 40), REPEAT('h',300); 300    100  20 2c 81  64   14  00
INSERT INTO mytest10 SELECT  REPEAT('i',20), REPEAT('j', 100), REPEAT('k', 40), REPEAT('l',100); 100 100 20 64   64  14 00 
INSERT INTO mytest10 SELECT  REPEAT('q',200), REPEAT('r', 100), REPEAT('s', 40), REPEAT('t',150); 150    100   200 96 80 64     c8  80 00
INSERT INTO mytest10 SELECT  REPEAT('u',128), REPEAT('v', 100), REPEAT('w', 40), REPEAT('x',127); 127 100   128 7f    64     80 80 00
例2
从这个插入记录来看, 长度的表达不仅和字段的定义有关, 还和插入的长度有关, 当长度的定义大于255时,  长度大于127时, 就用两个字节来表示(如下面这个表的最后一个字段), 当是127时只用一个字节来表示, 当等于128时就用两个字节来表示(80 80); 当一个字段的定义小于255时, 它的长度都用一个字节来表示, 不管大于还是小于127. create table mytest20(t1 VARCHAR(200), t2 VARCHAR(127), t3 VARCHAR(128), t4 VARCHAR(300)) ENGINE=INNODB CHARSET=latin1 row_format=compact;
INSERT INTO mytest20 SELECT  REPEAT('e',150), REPEAT('f', 100), REPEAT('g', 128), REPEAT('h',127);
127 128  100  150 7f    80    64    96 00

INSERT INTO mytest20 SELECT  REPEAT('i',200), REPEAT('j', 100), REPEAT('k', 128), REPEAT('l',128);
128      128   100  200 80 80   80      64   c8 00

2. NULL标志位         指示了该行数据列中是否有NULL值,这个字段的长度和表的列数有关,每一列对应一个bit位,低字节对应与高的列,即从右到左,分别对应第一列,第二列. . .(整个nulls空间中的位图是以从后面向前面的顺序来表示所有nullable列的null信息的。)。 (A single bit per nullable field to store whether the field isNULL, rounded up to a whole number of bytes. If a field is NULL its field value will be eliminated from the key or row portion of the record. If no fields are nullable, this bitmap is absent.)
create table mytest1(t1 VARCHAR(10), t2 VARCHAR(10), t3 CHAR(10), t4 VARCHAR(10), t5 VARCHAR(10) , t6 VARCHAR(10) , t7 VARCHAR(10), t8 VARCHAR(10), t9 VARCHAR(10), t10 VARCHAR(10), t11 VARCHAR(10), t12 VARCHAR(10), t13 VARCHAR(10), t14 VARCHAR(10), t15 VARCHAR(10), t16 VARCHAR(10), t17 VARCHAR(10), t18 VARCHAR(10)) ENGINE=INNODB CHARSET=latin1 row_format=compact;
INSERT INTO mytest1 VALUES(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); NULL标志:  03 ff ff
INSERT INTO mytest1 VALUES('a', 'bb', 'cccc', 'ddd', 'eeee', 'ffffff', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); NULL标志:  03 ff c0  (000 0011 1111 1111 1100 0000)   最后的6位表示 1, 2, 3, 4, 5, 6列不是NULL
INSERT INTO mytest1 VALUES('aaaa', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); NULL标志:  03 ff fe (1110)
INSERT INTO mytest1 VALUES('a', 'bb', NULL'ddd', 'eeee', 'ffffff', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); NULL标志:   03 ff c4 (1100 0100)  



3. 记录头信息          记录信息头的固定部分
Name Size Description
info_bits: ?? ??
() 1 bit unused or unknown
() 1 bit unused or unknown
deleted_flag 1 bit 1 if record is deleted:   该行是否已被删除(meaning the record is delete-marked (and will be actually deleted by a purge operation in the future).)
min_rec_flag 1 bit 1 if record is predefined minimum record: 如果为1,如果该记录是预先被定义为最小记录(meaning this record is the minimum record in a non-leaf level of the B+Tree): 对于非叶子页的最左记录,其上有一个标志REC_INFO_MIN_REC_FLAG (0x10UL),而叶子页没有这个标志
n_owned 4 bits number of records owned by this record:该记录拥有的记录数(The number of records “owned” by the current record in the page directory.)
heap_no 13 bits record's order number in heap of index page 索引堆中该记录的排序记录
record_type 3 bits 记录类型: 000 普通记录;001 表示B+树节点指针;010 表示Infimum记录;011 表示Supremum记录,1xx 保留
next_record 16 bits 页中下一条记录的相对位置: 即下一条记录起始地址相对于本记录的偏移。

4. 紧接着记录头信息的三个列是系统列: RowID :                    当没有主键时, 这个字段由Innodb自动创建的, 如果有主键时, 就用主键:   6bytes Transaction ID:        6 bytes Roll Pointer             7 bytes 

Roll Pointer的结构 bits     55: 1 INSERT           |        54 ~48               |    47 ~ 16                                       |                         0 ~ 15                                     |          --------------------------------------------------------------------------------------------------------- ------------------------------------------------           |INSERT or UPDATE | rollback segment ID  |   undo log segment page number  | undo log record offset in undo log segment page |



推荐阅读
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
author-avatar
mobiledu2502889283
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有