InnoDB 引擎中一条记录是怎样存储的
页是 MySQL 中磁盘和内存交互的基本单位,也是 MySQL 管理存储空间的基本单位。一个页一般是 16KB,当记录中的数据太多,当前页放不下的时候,会把多余的数据存储到其他页中,这种现象称为行溢出。
记录在磁盘上的存放方式称为 行格式,InnoDB 存储引擎到现在为止设计了 4 种不同类型的行格式,分别是 Compact
、Redundant
、Dynamic
和 Compressed
行格式。
Compact 行格式
变长字段长度列表
对于 varchar()
,text
,或者以变长字符集(比如 utf-8)存储的 char()
,等数据类型,存储多少字节的数据是不固定的,因此 InnoDB 会在记录的开头存储这些变长字段的真实数据占用的字节长度,形成一个变长字段长度列表,在这个列表中各变长字段占用的字节数按照列的顺序逆序存放。
变长字段长度列表中只存储值为 非 NULL 的列内容占用的长度,值为 NULL 的列的长度是不储存的 。并不是所有记录都有这个 变长字段长度列表 部分,比方说表中所有的列都不是变长的数据类型的话,这一部分就不需要有。
NULL 值列表
如果表中没有允许存储 NULL 的列,则 NULL 值列表 也不存在了,否则将每个允许存储 NULL 的列对应一个二进制位,二进制位按照列的顺序逆序排列。二进制位值为1表示该列的值为NULL。
MySQL 规定 NULL 值列表必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节的高位补 0。
记录头信息
由固定 5 个字节组成,之后讲数据页结构的时候会详细解释字段代表的含义
记录的真实数据
除了我们自己定义的列数据以外,MySQL 会为每个记录默认的添加一些列(也称为隐藏列),包括 row_id(DB_ROW_ID)、transaction_id(DB_TRX_ID)和 roll_pointer(DB_ROLL_PTR)
InnoDB 表对主键的生成策略:优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个 Unique
键作为主键,如果表中连 Unique
键都没有定义的话,则 InnoDB 会为表默认添加一个名为 row_id 的隐藏列作为主键。所以我们从上表中可以看出:InnoDB 存储引擎会为每条记录都添加 transaction_id 和 roll_pointer 这两个列,但是 row_id 是可选的(在没有自定义主键以及 Unique 键的情况下才会添加该列)。
Dynamic 和 Compressed 行格式
这两种行格式类似于 COMPACT 行格式,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实数据处存储字符串的前 768 个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。
Compressed 行格式和 Dynamic 不同的一点是,Compressed 行格式会采用压缩算法对页面进行压缩,以节省空间。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Redis 多机数据库
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论