### 表在文件系统中的表示
每个表的信息其实可以分为两种:
1. 表结构的定义
2. 表中的数据
`表结构`就是该表的名称是啥,表里边有多少列,每个列的数据类型是啥,有啥约束条件和索引,用的是啥字符集和比较规则吧啦吧啦的各种信息,这些信息都体现在了我们的建表语句中了。为了保存这些信息,`InnoDB`和`MyISAM`这两种存储引擎都在`数据目录`下对应的数据库子目录下创建了一个专门用于描述表结构的文件,文件名是这样:
~~~
表名.frm
~~~
#### InnoDB是如何存储表数据的
##### 系统表空间(system tablespace)
这个所谓的`系统表空间`可以对应文件系统上一个或多个实际的文件,默认情况下,`InnoDB`会在`数据目录`下创建一个名为`ibdata1`
在一个MySQL服务器中,系统表空间只有一份。从MySQL5.5.7到MySQL5.6.6之间的各个版本中,我们表中的数据都会被默认存储到这个***系统表空间***。
##### 独立表空间(file-per-table tablespace)
在MySQL5.6.6以及之后的版本中,`InnoDB`并不会默认的把各个表的数据存储到系统表空间中,而是为每一个表建立一个独立表空间,也就是说我们创建了多少个表,就有多少个独立表空间。使用`独立表空间`来存储表数据的话,会在该表所属数据库对应的子目录下创建一个表示该`独立表空间`的文件,文件名和表名相同,只不过添加了一个`.ibd`的扩展名而已,所以完整的文件名称长这样:
~~~
表名.ibd
~~~
比方说假如我们使用了`独立表空间`去存储`xiaohaizi`数据库下的`test`表的话,那么在该表所在数据库对应的`xiaohaizi`目录下会为`test`表创建这两个文件:
~~~
test.frm
test.ibd
~~~
##### 其他类型的表空间
随着MySQL的发展,除了上述两种老牌表空间之外,现在还新提出了一些不同类型的表空间,比如通用表空间(general tablespace)、undo表空间(undo tablespace)、临时表空间(temporary tablespace)吧啦吧啦的,具体情况我们就不细唠叨了,等用到的时候再提。
## 文件系统对数据库的影响
因为`MySQL`的数据都是存在文件系统中的,就不得不受到文件系统的一些制约,这在数据库和表的命名、表的大小和性能方面体现的比较明显,比如下边这些方面:
* 数据库名称和表名称不得超过文件系统所允许的最大长度。
每个数据库都对应`数据目录`的一个子目录,数据库名称就是这个子目录的名称;每个表都会在数据库子目录下产生一个和表名同名的`.frm`文件,如果是`InnoDB`的独立表空间或者使用`MyISAM`引擎还会有别的文件的名称与表名一致。这些目录或文件名的长度都受限于文件系统所允许的长度~
* 特殊字符的问题
为了避免因为数据库名和表名出现某些特殊字符而造成文件系统不支持的情况,`MySQL`会把数据库名和表名中所有除数字和拉丁字母以外的所有字符在文件名里都映射成`@+编码值`的形式作为文件名。比方说我们创建的表的名称为`'test?'`,由于`?`不属于数字或者拉丁字母,所以会被映射成编码值,所以这个表对应的`.frm`文件的名称就变成了`test@003f.frm`。
* 文件长度受文件系统最大长度限制
对于`InnoDB`的独立表空间来说,每个表的数据都会被存储到一个与表名同名的`.ibd`文件中;对于`MyISAM`存储引擎来说,数据和索引会分别存放到与表同名的`.MYD`和`.MYI`文件中。这些文件会随着表中记录的增加而增大,它们的大小受限于文件系统支持的最大文件大小。
## MySQL系统数据库简介
我们前边提到了MySQL的几个系统数据库,这几个数据库包含了MySQL服务器运行过程中所需的一些信息以及一些运行状态信息,我们现在稍微了解一下。
* `mysql`
这个数据库贼核心,它存储了MySQL的用户账户和权限信息,一些存储过程、事件的定义信息,一些运行过程中产生的日志信息,一些帮助信息以及时区信息等。
* `information_schema`
这个数据库保存着MySQL服务器维护的所有其他数据库的信息,比如有哪些表、哪些视图、哪些触发器、哪些列、哪些索引吧啦吧啦。这些信息并不是真实的用户数据,而是一些描述性信息,有时候也称之为元数据。
* `performance_schema`
这个数据库里主要保存MySQL服务器运行过程中的一些状态信息,算是对MySQL服务器的一个性能监控。包括统计最近执行了哪些语句,在执行过程的每个阶段都花费了多长时间,内存的使用情况等等信息。
* `sys`
这个数据库主要是通过视图的形式把`information_schema`和`performance_schema`结合起来,让程序员可以更方便的了解MySQL服务器的一些性能信息。
### 区(extent)的概念
表空间中的页实在是太多了,为了更好的管理这些页面,设计`InnoDB`的大叔们提出了`区`(英文名:`extent`)的概念。对于16KB的页来说,连续的64个页就是一个`区`,也就是说一个区默认占用1MB空间大小。不论是系统表空间还是独立表空间,都可以看成是由若干个区组成的,每256个区被划分成一组。画个图表示就是这样:
![](https://img.kancloud.cn/d3/42/d3422f83c59a4a9f2ebd94eb8fb940ac_662x547.png)
**表空间被划分为许多连续的`区`,每个区默认由64个页组成,每256个区划分为一组,每个组的最开始的几个页面类型是固定的**
### 段(segment)的概念
叶子节点有自己独有的`区`,非叶子节点也有自己独有的`区`。存放叶子节点的区的集合就算是一个`段`(`segment`),存放非叶子节点的区的集合也算是一个`段`。也就是说一个索引会生成2个段,一个叶子节点段,一个非叶子节点段。
为了考虑以完整的区为单位分配给某个段对于数据量较小的表太浪费存储空间的这种情况,`InnoDB`提出了一个碎片(fragment)区的概念,也就是在一个碎片区中,并不是所有的页都是为了存储同一个段的数据而存在的,而是碎片区中的页可以用于不同的目的,比如有些页用于段A,有些页用于段B,有些页甚至哪个段都不属于。碎片区直属于表空间,并不属于任何一个段。所以此后为某个段分配存储空间的策略是这样的:
* 在刚开始向表中插入数据的时候,段是从某个碎片区以单个页面为单位来分配存储空间的。
* 当某个段已经占用了32个碎片区页面之后,就会以完整的区为单位来分配存储空间。
### 区的分类
* 空闲的区:现在还没有用到这个区中的任何页面。
* 有剩余空间的碎片区:表示碎片区中还有可用的页面。
* 没有剩余空间的碎片区:表示碎片区中的所有页面都被使用,没有空闲页面。
* 附属于某个段的区。每一个索引都可以分为叶子节点段和非叶子节点段,除此之外InnoDB还会另外定义一些特殊作用的段,在这些段中的数据量很大时将使用区来作为基本的分配单位。
这4种类型的区也可以被称为区的4种状态(`State`)
| 状态名 | 含义 |
| :-: | :-: |
| `FREE` | 空闲的区 |
| `FREE_FRAG` | 有剩余空间的碎片区 |
| `FULL_FRAG` | 没有剩余空间的碎片区 |
| `FSEG` | 附属于某个段的区 |
处于`FREE`、`FREE_FRAG`以及`FULL_FRAG`这三种状态的区都是独立的,算是直属于表空间;而处于`FSEG`状态的区是附属于某个段的。
- 学习地址
- MySQL
- 查询优化
- SQL优化
- 关于or、in、not in、!=等走不走索引的说明
- 千万级数据查询优化
- MySQL 深度分页问题
- 嵌套循环 Block Nested Loop 导致索引查询慢
- MySQL增加日志统计表优化各种日志表的统计功能
- MySQL单机读写QPS(性能)优化
- sqlMode 置 select 的值可以比 group 里的多
- drop、delete、truncate的区别
- 尚硅谷MySQL数据库高级学习笔记
- MySQL架构
- 事务部分
- MySQL知识点
- mysql索引
- Linux docker安装 mysql 8.0.25
- docker 安装mysql 5.7
- mysql Field ‘xxx’ doesn’t have a default value
- mysql多实例
- docker中的sql文件导入
- mysql进阶知识
- mysql字符集
- 连接的原理
- redo日志
- InnoDB存储引擎
- InnoDB的数据存储结构
- B+树索引
- 文件系统-表空间
- Buffer Pool
- 亿级数据导入到es
- MySQL数据复制
- MySQL缺少主键的表数据
- mysql update 其中更新的字段根据另一个更新字段作为条件去更新
- MySQL指定字段值排序(将指定值排在前面)
- 设置MySQL连接数、时区
- Navicat15右键删除数据刷新就又恢复了
- MySQL替换字段部分内容
- Java和MySQL统计本周本月本季和年
- 分页时order by 排序数据重复,丢失
- mysql同一张表根据某个字段删除重复数据
- mysqldump定时全量热备
- 专题总结
- 事务
- MySQL事务
- spring事务
- spring事务本类调用
- spring事务传播行为
- spring事务失效问题
- 锁和Transactional注解一块使用的问题
- 数据安全
- 敏感数据
- SQL注入
- 数据源
- XSS
- 接口设计
- 缓存设计
- 限流
- 自定义注解实现根据用户做QPS限流
- 架构
- 高可用
- Java
- Unsatisfied dependency expressed through field ‘baseMapper‘
- mybatisplus多数据源
- 单个字母前缀的java变量
- spring
- spring循环依赖解决
- 事务@Transactional
- yml 文件配置信息绑定到java工具类的静态变量上
- @Configuration @Component 区别
- springboot启动yml文件报错
- spring方法重试注解Retryable
- spring读取yml集合数据
- spring自定义注解
- 获取resource下的图片资源
- 手机号和电话号的正则验证
- 获取字符串中的数字
- mybatis
- mybatis多参数添加数据并返回主键
- 统一异常处理
- 分组校验
- Java读取Python json.dumps 函数保存的redis数据
- springboot整合springCache
- 若依mybatis值为null的字段没有返回
- 若依
- 接口白名单
- @JsonFormat时区问题
- RequestParam.value() was empty on parameter 0
- jdk8和hutool请求第三方的https报错
- springMVC
- springMVC与vue使用post传数组
- elementUI 时间组件报错问题
- vue具名插槽slot
- springboot配置maven的profiles(配置微服务多环境切换打包)
- resources 配置文件读取顺序
- Windows的cmd部署jar注意事项
- Java基础
- JUC(锁-并发-线程池)
- CAS
- Java 锁简介
- synchronized和Logk有什么区别?用新的ock有什么好处
- synchronized锁介绍
- CompletableFuture
- 多线程
- 线程池
- 集合类
- map见过的小问题
- 退出双层循环
- StringBuilder和StringBuffer核心区别
- 日志打印
- 打印log日志
- log日志文件生成配置
- 日期时间
- 时间戳转为时间
- 并发工具
- 连接池
- http调用
- 内网访问天地图
- 判等问题
- 数值计算
- null问题
- 异常处理
- 文件IO
- 序列化
- 内存溢出OOM
- 子线程的错误, 全局异常处理捕获不到
- vue同一个项目访问多个不同ip地址接口
- Autowired注解导入为null
- shiro
- UnavailableSecurityManagerException错误
- Windows服务器80端口被占用
- java图片增加水印
- springcloud
- Feign方法配置错误导致jar包启动失败
- feign调用超时
- 定时任务quartz
- JavaPOI导出Excel
- 合并行和列
- 设置样式
- 设置背景色
- docker
- Linux 安装
- docker命令
- docker网络
- docker数据卷
- dockerfile
- docker安装ping命令
- docker-compose
- docker-compose文件内容介绍
- Linux关闭docker开机启动
- jar打包为镜像
- 迁移docker容器存储位置
- Nginx
- Linux在线安装Nginx
- nginx.conf 核心配置文件
- vue 和 nginx 刷新页面会报404
- nginx 转发给三个集群的tomcat
- ServerName匹配规则
- Nginx负载均衡策略
- location 匹配规则
- Nginx 搭建前端调用后台接口的集群
- alias与root
- nginx 拦截 post 请求, 带参数转发到前端页面
- 防盗链配置
- Nginx的缓存
- 通用Nginx配置
- nginx配置文件服务器
- 后台jar包得不到正确ip,nginx代理时要处理
- 升级使用websocket协议
- 设置IP黑/白名单
- Redis
- 缓存数据一致性
- 内存淘汰策略
- Redis数据类型
- gmt6
- Linux安装GMT6
- GMT6配置中文
- GMT文件修改Windows版本到Linux版本
- 注意GMT不同字体导致符号不同的问题
- GMT绘制南海诸岛小图
- GMT生成中文图例
- elasticsearch
- 安装配置
- Linux安装配置elasticsearch7.6.2
- Linux 安装 kibana 7.6.2
- 安装7.6.2中文分词器
- docker 安装elasticsearch7.6.2
- 安装Logback7.6.2
- springboot使用
- 0. elasticsearch账号密码模式访问
- 1. 配置连接
- 2. 索引
- 3. 批量保存更新
- Result window is too large 10000
- elasticsearch 分词的字段做排序 fielddata, 设置fielddata=true 无效果
- elasticsearch 完全匹配查询(精确查询)
- 模糊搜索
- 日期区间查询
- 6.x基础知识
- 自定义词库
- elasticsearch集群
- 搜索推荐Suggester
- 查询es保存的数组
- 亿级mysql数据导入到es
- es 报错 ORBIDDEN/12/index read-only
- es核心概念
- es的分布式架构原理
- 优化大数据量时的ES查询性能
- canal
- 1. mysql的Binlog
- 2. Canal 的工作原理
- 3. canal同步es
- JVM
- 1 类的字节码
- 2. 类的加载
- JVM知识点
- Maven
- 依赖冲突
- xxl-job
- docker 安装配置 xxl-job
- idea
- springboot启动报错命令过长
- services统一启动微服务各模块
- 云服务器安装宝塔面板
- 突然出现启动或者运行特别慢
- 有导入依赖但是显示红色同时点击进去也有依赖
- Linux
- sh文件执行报错: command not found
- 使用vagrant安装虚拟机
- Linux 开启端口
- 开放端口
- 复制文件夹及其文件到另一个文件夹
- 两个服务器之间映射端口
- TCP协议
- 分层模型
- TCP概述
- 支撑 TCP 协议的基石 —— 首部字段
- 数据包大小对网络的影响 —— MTU 与 MSS 的奥秘
- 端口号
- 三次握手
- TCP 自连接
- 四次挥手
- TCP 头部时间戳
- 分布式
- 分布式脑裂问题
- 分布式事务
- 基础知识
- 实现分布式事务的方案
- 阿里分布式事务中间件seata
- 幂等性问题
- 其他工具
- webstorm git提交代码后project目录树不显示
- 消息队列
- 如何保证消费的顺序
- 数据结构
- 漫画算法:小灰的算法之旅