InnoDB 引擎中一条记录是怎样存储的

发布于 2022-01-13 12:58:28 字数 1873 浏览 975 评论 0

页是 MySQL 中磁盘和内存交互的基本单位,也是 MySQL 管理存储空间的基本单位。一个页一般是 16KB,当记录中的数据太多,当前页放不下的时候,会把多余的数据存储到其他页中,这种现象称为行溢出。

记录在磁盘上的存放方式称为 行格式,InnoDB 存储引擎到现在为止设计了 4 种不同类型的行格式,分别是 CompactRedundantDynamic 和 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

文章
评论
84963 人气
更多

推荐作者

微信用户

文章 0 评论 0

小情绪

文章 0 评论 0

ゞ记忆︶ㄣ

文章 0 评论 0

笨死的猪

文章 0 评论 0

彭明超

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文