MySQL 行溢出数据
MySQL 行溢出数据
MySQL 对一条记录占用的最大储存空间是有限制的,除了 BLOB 和 TEXT 类型之外,其他所有列 (不包括隐藏列和记录头信息) 占用的字节长度不能超过 65535 个字节,当记录长度超过限制时,MySQL 会建议使用 TEXT 或 BLOB 类型
储存数据
储存上限 65535 个字节不仅包含本身的数据,还包含一些其他数据 (storage overhead),以 VERCHAR 类型为例,共需要 3 部分储存空间:
- 真实数据
- 真实数据占用的字节长度
- NULL 值标识,NOT NULL 列没有这部分
当使用 ascii 字符集时:如果 '真实数据占用的字节长度' 占用两个字节,NULL 值标识占用一个字节,则真实数据最多只能存储 65532 个字符
当使用 utf8 字符集时:如果 '真实数据占用的字节长度' 占用两个字节,NULL 值标识占用一个字节,则真实数据最多只能存储 21844 (65532 / 3) 个字符
行溢出
由于 MySQL 中以页为基本单位来管理储存空间的,所有的记录都会被分配到页中
由于一个页一般为 16KB (16384 个字节),而一个 VERCHAR 最多可以存储 65532 个字节,所以会出现一个页存放不下一条记录的情况,造成行溢出
不仅是 VERCHAR,BLOB 和 TEXT 也会发生行溢出
存储方式
对于不同行格式,有不同储存溢出页的方式
Compact & Reduntant
当发生行溢出时,在 Compact 和 Reduntant 中,'记录的真实数据' 处只会存储一部分 (768 字节的) 数据,剩下的数据存储在几个其他的页 (溢出页) 中 (以链表的方式连接),在 '记录的真实数据' 处用 20 个字节存储这些页的地址 (包含分散在其他页面中的数据的占用的字节数)
Dynamic & Compressed
它们不会在 '记录的真实数据' 处储存真实数据的前 768 个字节,而是把所有的字节都存储到其他页面中,只储存其他页面的地址