首先,我们得知道数据实际存储的位置。每个创建的数据库会在 /var/lib/mysql/ 目录下,根据数据库名创建相应目录,表的数据文件就存放在其中。例如,名为 my_test 的数据库,其 t_order 表的数据就存储在「表名字.idb」文件中,被称为独占表空间文件。深入到表空间结构,InnoDB 以段(segment)、区...
MySQL 的 NULL 值是怎么存放的?
大家好,针对 MySQL 中 NULL 值的存储机制,我们来一起探讨。当面对面试中关于数据库底层存储的问题时,了解行记录的存储结构至关重要。MySQL 的数据存储并非简单的文件,而是由多种因素决定,其中 InnoDB 存储引擎是常用的,它的存储行为由引擎实现。
首先,我们得知道数据实际存储的位置。每个创建的数据库会在 /var/lib/mysql/ 目录下,根据数据库名创建相应目录,表的数据文件就存放在其中。例如,名为 my_test 的数据库,其 t_order 表的数据就存储在「表名字.idb」文件中,被称为独占表空间文件。
深入到表空间结构,InnoDB 以段(segment)、区(extent)、页(page)和行(row)为单位。行记录存储在数据页中,为了提高效率,数据不按行读写,而是以页为单位。每个页默认大小是 16KB,一次读写至少是 16KB,最小刷新单位也是 16KB。
区的大小为 1MB,用于解决页间物理位置不连续导致的随机 I/O 问题,使得查询性能提升。区由多个页组成,形成一个连续的存储区域。段则是多个区的集合,其中包括数据段、索引段和回滚段等。
说到 NULL 值,InnoDB 采用 Compact 行格式,将 NULL 值存储在单独的「NULL 值列表」中,一个二进制位对应一个字段,列的顺序决定了位的顺序。NULL 值列表是可变的,用整数个字节表示,不足整数位的在高位补0。NULL 值列表的存在是基于列是否允许 NULL,如果所有字段都为 NOT NULL,则不会有 NULL 值列表。
记录的额外信息包括变长字段长度列表,存储变长字段的实际占用字节数,以及记录头信息,包括 row_id、trx_id 和 roll_pointer。这些隐藏字段对于 MVCC(多版本并发控制)机制的理解至关重要。
关于 varchar(n) 类型的列,MySQL 有特定的字节限制。一行记录的最大存储量是 65535 字节,减去「变长字段长度列表」和「NULL 值列表」的占用空间,实际能存储的 varchar(n) 字符数会相应减少。对于单字段 ascii 表,如果允许 NULL,最大可存储的 varchar(n) 字符数是 65532。
当行溢出,即数据超过一页时,InnoDB 会将溢出部分存放在「溢出页」,并且记录真实数据部分会包含指向溢出页的地址。对于 Compressed 和 Dynamic 行格式,处理行溢出的方式略有不同,但都是通过指针指向溢出数据。
总的来说,理解 MySQL 中 NULL 值的存储方式,包括行格式、变长字段和 NULL 值列表的处理,可以帮助你应对面试中的相关问题,深入了解数据库底层工作原理。希望这些信息对你有所帮助!2024-08-17