表数据对应的文件
首先我们要知道,我们创建的数据库的信息被存放在数据目录(即 my.cnf
配置文件中通过 datadir
指定的目录)下以数据库名为目录名的目录下。
创建 test
数据库:
mysql> create database test;
查看数据目录:
$ ll | grep '^d'
drwxr-x--- 2 mysql mysql 4096 Apr 21 21:15 mysql
drwxr-x--- 2 mysql mysql 8192 Apr 21 21:15 performance_schema
drwxr-x--- 2 mysql mysql 8192 Apr 21 21:15 sys
drwxr-x--- 2 mysql mysql 105 Apr 22 21:03 test
可以看到有一个对应 test
库的目录 test
。
我们还需要了解,在对应库创建的表的数据被存放在对应库目录下,此时表数据的存储方式会因存储引擎的不同而不同,下面以 MYISAM 和 INNODB 引擎为例说明。
MYISAM
在 test
库下执行下面 SQL 创建 user1
表:
create table user1(
id int,
name varchar(20)
) engine=myisam default charset=utf8
查看数据目录下的 test
目录:
$ ll test/ | grep user1
-rw-r----- 1 mysql mysql 8586 Apr 22 20:57 user1.frm
-rw-r----- 1 mysql mysql 20 Apr 22 20:58 user1.MYD
-rw-r----- 1 mysql mysql 1024 Apr 22 20:58 user1.MYI
结果如下图:
即当表的存储引擎为 MYISAM 时,表在数据目录会生成如下三个文件:
表名.frm
:存放了对应表的列信息;表名.MYD
:存放了对应表的数据行信息;表名.MYI
,存放了对应表的索引信息;
INNODB
在 test
库下执行下面 SQL 创建 user2
表:
create table user2(
id int,
name varchar(20)
) engine=innodb default charset=utf8
查看数据目录下的 test
目录:
$ ll test/ | grep user2
-rw-r----- 1 mysql mysql 8586 Apr 22 21:03 user2.frm
-rw-r----- 1 mysql mysql 98304 Apr 22 21:03 user2.ibd
结果如下图:
即当表的存储引擎为 INNODB 时,表在数据目录会生成如下两个文件:
表名.frm
:存放了对应表的列信息;表名.idb
:存放了索引和数据行信息;
INNODB 表数据存储结构
1、首先,数据肯定是被存储在硬盘(disk)中;
2、硬盘的最小存储单位为扇区(sector),一个扇区是由同一磁道上的连续 512 Bytes 大小的空间组成;
3、对 Linux 文件系统来说,读取数据的最小粒度是块(block),一个块通常由同磁道的 8 个连续的扇区组成,即其大小为 4 KB;
4、对 MySQL 来说,它的每一条数据是以行(row)的形式存在,而行被存放在页(page) 中,每个页是由文件系统中连续的 4 个块组成,即每个页的大小为 16KB;
5、页被存放在簇(extents)中,每一个簇是由连续的 64 个页组成,即每个簇的大小为 1MB;
6、簇是构成段的基本元素(segments),一个段由多个簇组成,一个簇是物理上连续分配的一个段空间,每一个段至少会有一个簇,在创建一个段时会创建一个默认的簇。如果存储数据时,一个簇已经不足以放下更多的数据,此时需要从这个段中分配一个新的簇来存放新的数据。一个段所管理的空间大小是无限的,可以一直扩展下去,但是扩展的最小单位就是簇。 段是表空间文件中的主要组织结构,它是一个逻辑概念,用来管理物理文件(如 user2.idb),是构成索引、表、回滚段的基本元素;
综上所述可以做个小结:扇区(sector)、块(block)、页(page)、簇(extents)、段(segments)等设计理念,都是为了能够让程序在 OS 到硬盘(disk)的逻辑操作到物理操作都能够保证尽可能“连续”IO,以提升 IO 效率。
评论区