👏作者简介:大家好,我是小周同志,25届双非校招生Java选手,很高兴认识大家
📕学习出处:本文是学自小林coding (xiaolincoding.com) 网站的MYSQL图解篇
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
MySQL 的数据存放在哪个文件?
当我们输入下面的命令之后:就可以看到 /var/lib/mysql
mysql> SHOW VARIABLES LIKE 'datadir'; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | datadir | /var/lib/mysql/ | +---------------+-----------------+ 1 row in set (0.00 sec)
创建一个数据库时, 都会在 /var/lib/mysql/ 目录里面创建一个以 database 为名的目录
在数据库中创建表时,
[root@root]#ls /var/lib/mysql/test db.opt t_test.frm t_test.ibd
db.opt:用来存储当前数据库的默认字符集和字符校验规则。
t_test.frm:t_test 的表结构会保存在这个文件。在 MySQL 中建立一张表都会生成一个.frm 文件,用来保存每个表的元数据信息的,主要包含表结构定义。
t_test.ibd:t_test 的表数据会保存在这个文件。表数据既可以存在共享表空间文件(文件名:ibdata1)里,也可以存放在独占表空间文件(文件名:表名字.ibd)。这个行为是由参数 innodb_file_per_table 控制的,若设置了参数 innodb_file_per_table 为 1,则会将存储的数据、索引等信息单独存储在一个独占表空间,从 MySQL 5.6.6 版本开始,它的默认值就是 1 了,因此从这个版本之后, MySQL 中每一张表的数据都存放在一个独立的 .ibd 文件。
总结(回答问题): MySQL 5.6.6之后,mysql的数据默认存放到 .ibd后缀的文件(独占表空间文件) 中。
InnoDB 行格式有哪些?
InnoDB 提供了 4 种行格式:Redundant(冗余)、Compact(紧凑)、Dynamic(动态) 和 Compressed(压缩行)
Redundant:很古老的行格式, MySQL 5.0 版本之前用的行格式,现在基本没人用了。
Compact: 是一种紧凑的行格式,设计的初衷就是为了让一个数据页中可以存放更多的行记录,从 MySQL 5.1 版本之后,行格式默认设置成 Compact。
Dynamic 和 Compressed 两个都是紧凑的行格式,它们的行格式都和 Compact 差不多,因为都是基于 Compact 改进一点东西。从 MySQL5.7 版本之后,默认使用 Dynamic 行格式。
其中 Dynamic 和 Compressed 与 Compact格式特别像
COMPACT 行格式长什么样?
(结构如图:来自小林coding)
记录的额外信息
记录的额外信息包含 3 个部分:变长字段长度列表、NULL 值列表、记录头信息。
1. 变长字段长度列表
表的一行数据中,找出类型为 varchar的字段,并将其倒序存储在 变长字段长度列表。
比如:表的一行数据中,varchar字段name为11,varchar字段phone是123。
那么这个行记录的变长字段长度列表存储样式为 03 02
注意:
为什么「变长字段长度列表」的信息要按照逆序存放?
因为这样可以 使得位置靠前的记录的真实数据和数据对应的字段长度信息可以同时在一个 CPU Cache Line 中,这样就可以提高 CPU Cache 的命中率。
每个数据库表的行格式都有「变长字段字节数列表」吗?
当数据表没有变长字段的时候,比如全部都是 int 类型的字段,这时候表里的行格式就不会有「变长字段长度列表」了
2. NULL 值列表
如果存在允许 NULL 值的列,则每个列对应一个二进制位(bit),二进制位按照列的顺序逆序排列。
二进制位的值为
1
时,代表该列的值为NULL。二进制位的值为
0
时,代表该列的值不为NULL。另外,NULL 值列表必须用整数个字节的位表示(1字节8位),如果使用的二进制位个数不足整数个字节,则在字节的高位补
0
。注意:
每个数据库表的行格式都有 NULL 值列表 吗?
NULL 值列表 不是必须的。
当数据表的字段都定义成 NOT NULL 的时候,这时候表里的行格式就不会有 NULL 值列表了。
所以在设计数据库表的时候,通常都是建议将字段设置为 NOT NULL,这样可以至少节省 1 字节的空间(NULL 值列表至少占用 1 字节空间)。
NULL 值列表 是固定 1 字节空间吗?如果这样的话,一条记录有 9 个字段值都是 NULL,这时候怎么表示?
NULL 值列表 的空间不是固定 1 字节的。
当一条记录有 9 个字段值都是 NULL,那么就会创建 2 字节空间的 NULL 值列表,以此类推。
记录的真实数据
1. row_id
如果我们建表的时候指定了主键或者唯一约束列,那么就没有 row_id 隐藏字段了。如果既没有指定主键,又没有唯一约束,那么 InnoDB 就会为记录添加 row_id 隐藏字段。row_id不是必需的,占用 6 个字节。
2. trx_id
事务id,表示这个数据是由哪个事务生成的。 trx_id是必需的,占用 6 个字节。
3. roll_pointer
这条记录上一个版本的指针。roll_pointer 是必需的,占用 7 个字节。