侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

MySQL数据在文件系统中的存储

zze
zze
2020-04-22 / 0 评论 / 0 点赞 / 432 阅读 / 3069 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

表数据对应的文件

首先我们要知道,我们创建的数据库的信息被存放在数据目录(即 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

结果如下图:
image.png

即当表的存储引擎为 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

结果如下图:
image.png

即当表的存储引擎为 INNODB 时,表在数据目录会生成如下两个文件:

  • 表名.frm:存放了对应表的列信息;
  • 表名.idb:存放了索引和数据行信息;

INNODB 表数据存储结构

image.png

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 效率。

0

评论区