InnoDB 、 MyISAM 这样的存储引擎都是把表存储在磁盘上的,操作系统用文件系统来管理磁盘。
数据目录
MySQL服务器程序在启动时会到文件系统的某个目录下加载一些文件,之后在运行过程中产生的数据也都会存储到这个目录下的某些文件中,这个目录就称为 数据目录。
查询MySQL的数据目录
执行下面SQL:
show variables like 'datadir';
输出如下:
MySQL数据库和表在文件系统的表示
例如我们创建一个数据库和表:
create database spring_security;
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`created_time` datetime DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`updated_time` datetime DEFAULT NULL,
`user_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3
文件系统中显示:
Administrator@DESKTOP-2TA9FLB MINGW64 /f/data/MySQL/8.0.31
$ ll |grep spring_security
drwxr-xr-x 1 Administrator 197121 0 12月 3 21:56 spring_security/
Administrator@DESKTOP-2TA9FLB MINGW64 /f/data/MySQL/8.0.31
$ ll spring_security/
total 128
-rw-r--r-- 1 Administrator 197121 114688 12月 3 21:58 user.ibd
在文件系统中我们可以看到一个和database、表同名的文件夹和文件。
系统表空间(system tablespace)
系统表空间 可以对应文件系统上一个或多个实际的文件,默认情况下, InnoDB 会在 数据目录 下创
建一个名为 ibdata1大小为 12M 的文件,这个文件就是对应的 系统表空间 在文件系统上的表示。当12M用完后,ibdata1文件会自动增加文件大小,因为这个文件是 自扩展文件。
需要注意的一点是,在一个MySQL服务器中,系统表空间只有一份。从MySQL5.5.7到MySQL5.6.6之间的各个版本中,我们表中的数据都会被默认存储到这个 系统表空间。
Administrator@DESKTOP-2TA9FLB MINGW64 /f/data/MySQL/8.0.31
$ ll -h |grep ibdata1
-rw-r--r-- 1 Administrator 197121 12M 2月 12 10:48 ibdata1
独立表空间(file-per-table tablespace)
MySQL5.6.6以及之后的版本中, InnoDB 并不会默认的把各个表的数据存储到系统表空间中,而是为每一个表建立一个独立表空间,也就是说我们创建了多少个表,就有多少个独立表空间。
使用 独立表空间 来存储表数据的话,会在该表所属数据库对应的子目录下创建一个表示该 独立表空间 的文件,文件名和表名相同,只不过添加了一个 .ibd 的扩展名而已,所以完整的文件名称长这样:表名.ibd。
user.ibd 文件就用来存储 user 表中的数据和索引。
查询MySQL使用独立表空间还是系统表空间:
show variables like 'innodb_file_per_table';
当 innodb_file_per_table 的值为 OFF 时,代表使用系统表空间;当 innodb_file_per_table 的值为 ON 时,代表使用独立表空间。不过 innodb_file_per_table 参数只对新建的表起作用,对于已经分配了表空间的表并不起作用。
把已经存在系统表空间中的表转移到独立表空间,可以使用下边的语法:
ALTER TABLE 表名 TABLESPACE [=] innodb_file_per_table;
alter table user tablespace =innodb_file_per_table
把已经存在独立表空间的表转移到系统表空间中,可以使用下边的语法:
ALTER TABLE 表名 TABLESPACE [=] innodb_system;
区(extent)的概念
表空间中的页实在是太多了,为了更好的管理这些页面,InnoDB提出了 区 (英文名: extent )的概念。
对于16KB的页来说,连续的64个页就是一个 区 ,也就是说一个区默认占用1MB空间大小。
不论是系统表空间还是独立表空间,都可以看成是由若干个区组成的,每256个区被划分成一组。
其中 extent 0 ~ extent 255 这256个区算是第一个组, extent 256 ~ extent 511 这256个区算是第二个
组, extent 512 ~ extent 767 这256个区算是第三个组。
段(segment)的概念
MyISAM表数据存储
在 MyISAM 中的索引全部都是 二级索引 ,该存储引擎的数据和索引是分开存放的。所以在文件系统
中也是使用不同的文件来存储数据文件和索引文件。
和 InnoDB 不同的是, MyISAM 并没有什么所谓的 表空间 一说,表数据都存放到对应的数据库子目录下。
例如我们创建一个表:
create table myisam_demo
(
id int auto_increment,
constraint myisam_demo_pk
primary key (id)
) engine=myisam default charset utf8mb4;
那么对应的目录文件:
Administrator@DESKTOP-2TA9FLB MINGW64 /f/data/MySQL/8.0.31
$ ll spring_security |grep myisam_demo
-rw-r--r-- 1 Administrator 197121 0 2月 12 11:27 myisam_demo.MYD
-rw-r--r-- 1 Administrator 197121 1024 2月 12 11:27 myisam_demo.MYI
-rw-r--r-- 1 Administrator 197121 2015 2月 12 11:27 myisam_demo_381.sdi
myisam_demo.MYD:代表表的数据文件,也就是我们插入的用户记录;
myisam_demo.MYI:代表表的索引文件,我们为该表创建
的索引都会放到这个文件中。
MySQL系统数据库简介
MySQL有几个内置的数据库,这几个数据库包含了MySQL服务器运行过程中所需的一些信息以及
一些运行状态信息。
mysql
mysql数据库贼核心,它存储了MySQL的用户账户和权限信息,一些存储过程、事件的定义信息,一些运行过程中产生的日志信息,一些帮助信息以及时区信息等。
information_schema
information_schema数据库保存着MySQL服务器维护的所有其他数据库的信息,比如有哪些表、哪些视图、哪些触发器、哪些列、哪些索引等。这些信息并不是真实的用户数据,而是一些描述性信息,有时候也称之为元数据。
performance_schema
performance_schema数据库里主要保存MySQL服务器运行过程中的一些状态信息,算是对MySQL服务器的一个性能监控。包括统计最近执行了哪些语句,在执行过程的每个阶段都花费了多长时间,内存的使用情况等等信息。
sys
sys数据库主要是通过视图的形式把 information_schema 和 performance_schema 结合起来,让程序员可以更方便的了解MySQL服务器的一些性能信息。