为啥阿里巴巴不建议MySQL使用Text类型?( 二 )


行记录格式:
Variable-length offset listrecord_headercol1_valuecol2_value…….text_value字段长度偏移列表记录头信息,占48字节列1数据列2数据…….Text列指针数据
具有以下特点:

  • 存储变长列的前768 Bytes在索引记录中,剩余的存储在overflow page中,对于固定长度且超过768 Bytes会被当做变长字段存储在off-page中 。
  • 索引页中的每条记录包含一个6 Bytes的头部,用于链接记录用于行锁 。
  • 聚簇索引的记录包含用户定义的所有列 。另外还有一个6字节的事务ID(DB_TRX_ID)和一个7字节长度的回滚段指针(Roll pointer)列 。
  • 如果创建表没有显示指定主键,每个聚簇索引行还包括一个6字节的行ID(row ID)字段 。
  • 每个二级索引记录包含了所有定义的主键索引列 。
  • 一条记录包含一个指针来指向这条记录的每个列,如果一条记录的列的总长度小于128字节,这个指针占用1个字节,否则2个字节 。这个指针数组称为记录目录(record directory) 。指针指向的区域是这条记录的数据部分 。
  • 固定长度的字符字段比如CHAR(10)通过固定长度的格式存储,尾部填充空格 。
  • 固定长度字段长度大于或者等于768字节将被编码成变长的字段,存储在off-page中 。
  • 一个SQL的NULL值存储一个字节或者两个字节在记录目录(record dirictoty) 。对于变长字段null值在数据区域占0个字节 。对于固定长度的字段,依然存储固定长度在数据部分,为null值保留固定长度空间允许列从null值更新为非空值而不会引起索引的分裂 。
  • 对varchar类型,Redundant行记录格式同样不占用任何存储空间,而CHAR类型的NULL值需要占用空间 。
其中变长类型是通过长度 + 数据的方式存储,不同类型长度是从1到4个字节(L+1 到 L + 4),对于TEXT类型的值需要L Bytes存储value,同时需要2个字节存储value的长度 。同时Innodb最大行长度规定为65535 Bytes,对于Text类型,只保存9到12字节的指针,数据单独存在overflow page中 。
Compact行格式这种行格式比redundant格式减少了存储空间作为代价,但是会增加某些操作的CPU开销 。如果系统workload是受缓存命中率和磁盘速度限制,compact行格式可能更快 。如果你的工作负载受CPU速度限制,compact行格式可能更慢,Compact 行格式被所有file format所支持 。
行记录格式:
Variable-length field length listNULL标志位record_headercol1_valuecol2_value…….text_value变长字段长度列表
记录头信息-列1数据列2数据…….Text列指针数据
Compact首部是一个非NULL变长字段长度的列表,并且是按列的顺序逆序放置的,若列的长度小于255字节,用1字节表示;若大于255个字节,用2字节表示 。变长字段最大不可以超过2字节,这是因为MySQL数据库中varchar类型最大长度限制为65535,变长字段之后的第二个部分是NULL标志位,表示该行数据是否有NULL值 。有则用1表示,该部分所占的字节应该为1字节 。
所以在创建表的时候,尽量使用NOT NULL DEFAULT '',如果表中列存储大量的NULL值,一方面占用空间,另一个方面影响索引列的稳定性 。
具有以下特点: