这篇文章是自己学习mysql随手写的杂记,编辑混乱且不够严谨,请勿参考,谢谢!

mysql innodb引擎将数据存储在磁盘中,不同的引擎存储形式不同,有的则不需要存储,比如memory引擎。

innodb引擎底层数据的存储格式形式如下:

变长字段长度列表

NULL值列表

头信息

列1值

列2值

列n值.......

前面三个单元格是记录的附加信息,为了标识和管理记录而添加的。头信息后面的是记录的真实数据部分,不过有三个隐藏的属性,db_row_id,db_transaction_id,db_roll_pointer分别是记录唯一标识,事务id,回滚指针等等。

如果建表时有主键或unique键,则采用其作为db_row_id,否则系统会生成一个来唯一标识一条记录。

db_transaction_id和db_roll_pointer在事务中会使用到。

变长字段如varchar,text等都属于此类字段,如果有col1,col2,col3变长字段,则会在变长字段长度列表栏位逆序存放真实数据所占字节数,需要注意的是:如果该列值为NULL,则变长字段长度列表是不会存该NULL值所占字节长度的如果该列所允许存储的最大字节长度为255且真实数据所占字节超过127个字节则采用2个字节存储变长字段所占字节数,否则采用1个字节数来存储。对于CAHR(M)类型的列,虽然是定长列,但是如果编码字符集是变长字符集比如utf8(采用1-3个变长字节编码),则该列数据所占字节数还是会被加入到变长字段长度列表中的。NULL值列表只存储允许为NULL的列的NULL值情况,如果没有允许为NULL的列,则该NULL值列表则不存在。其中,存储时:1为NULL,0为非NULL。注意该部分需要整数个字节来表示,不足部分高位补0。头信息比较复杂,如下所示:

mysql存列表 mysql 列存储_mysql

mysql规定:除BLOB和Text列除外,其他列存储的数据(不包括隐藏列和记录头信息)最大不能超过65535个字节。

一个VARCHAR(M)列存储的数据所占空间包括:

  • 真实数据
  • 真实数据占用字节的长度
  • NULL值标识,如果该列有NOT NULL属性则可以没有这部分存储空间

对于VARCAHR(M),如果采用的是ASCII字符集(1个字符使用一个字节表示,是定长字符集),且允许为NULL(去除1个字节),真实数据占用字节数去除2个字节。那么实际真实数据所占最大字节数为65535-2-1=65532,则M为65532/1,如果是gbk字符集,则为65532/2,utf8字符集为65532/3。

鉴于CPU和磁盘之间无法跨越的速度鸿沟,mysql读取记录时,按页为单位,写入时,也是以页为单位。一个页的大小为16kb,但是前面的所述一个列所允许存储的最大字节数为65535字节,那么很可能一个列存储的数据单个页无法装载,此时会把记录的部分数据放到其他页中存储,这称为"行溢出"。

对于compact行格式而言,列真实数据的前768个字节用于存储数据的一部分,后面的20字节用于指向存储剩余数据的页地址。

dynamic类型的行格式与其不同的是:列真实数据处不存储数据的前768个字节,而是把全部数据放到其他页中存储,此处只存的是指向其他页的地址。

compressed页会对数据压缩,节省存储空间。

完。