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

发布于 2022-01-13 12:58:28 字数 1873 浏览 967 评论 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

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

0 文章
0 评论
84960 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

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