### 表在文件系統中的表示
每個表的信息其實可以分為兩種:
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個區被劃分成一組。畫個圖表示就是這樣:

**表空間被劃分為許多連續的`區`,每個區默認由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
- Double轉String出現E的問題
- springboot接收前端表單提交多字段和上傳文件
- 子線程的錯誤, 全局異常處理捕獲不到
- vue同一個項目訪問多個不同ip地址接口
- Autowired注解導入為null
- shiro
- UnavailableSecurityManagerException錯誤
- Windows服務器80端口被占用
- java圖片增加水印
- springcloud
- Feign方法配置錯誤導致jar包啟動失敗
- feign調用超時
- Springcloud從Nacos的yml文件讀取出錯
- 定時任務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黑/白名單
- vue項目get請求Nginx返回html頁面post返回405錯誤
- Nginx限制所有接口流量
- 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目錄樹不顯示
- 消息隊列
- 如何保證消費的順序
- 數據結構
- 漫畫算法:小灰的算法之旅
- oracle