MySQL數據 在 磁盤上是什么樣子的,取決于所使用的存儲引擎。存儲于引擎 是作用在 表! 上的
。
存儲引擎
百度百科是這樣定義存儲引擎的:MySQL 中的數據用各種不同的技術存儲在文件(或者內存)中,這些不同的技術以及配套的相關功能
在 MySQL 中被稱作 存儲引擎。
簡單來說就是不同的存儲引擎,我們的數據存儲的格式也會不一樣。
我們知道 現在 MySQL 中常用的存儲引擎有兩種:MyISAM 和 InnoDB。
- MySQL 5.5之前,MyISAM 是 默認的 存儲引擎
- MySQL 5.5開始,InnoDB 是 默認的 存儲引擎
區別
MyISAM | InnoDB | |
---|---|---|
事務 | 不支持? | 支持 |
表/行鎖 | 只有表鎖 | 還引入了行鎖 |
外鍵 | 不支持? | 支持? |
全文索引 | 支持? | 版本5.6 開始支持 |
讀寫速度 | 更快 | 更慢 |
從上面可以看出,MyISAM 最致命的一點就是不支持事務,而 InnoDB 支持。所以現在 InnoDB 已經成為我們使用的標配、最主流的存儲引擎了。
命令工具
查詢當前數據庫支持的存儲引擎
show engines;
查詢當前默認的存儲引擎
show variables like '%storage_engine%';
查詢表的相關信息
show table status like '表名';
MyISAM
每個 MyISAM 表 都有 3個文件存儲在磁盤上。這些文件的 名稱 以 表名 開頭,以 擴展名 指示文件類型。
-
.frm
文件(frame)存儲表結構
; -
.MYD
文件(MY Data)存儲表數據
; -
.MYI
文件(MY Index)存儲表索引
。
MySQL 里的數據 默認是 存放在安裝目錄下的 data 文件夾
中,也可以自己修改。
下面 以 MyISAM 作為存儲引擎 創建一張表 t_user_myisam。
.MYI 文件 組織索引的方式就是 B+tree。葉子節點 的 value 處存放的就是索引所在行的 磁盤文件地址。
查找過程
首先會判斷查找條件 where 中的字段 是否是 索引字段,
如果是就會先拿著這字段去 .MYI 文件里通過 B+tree 快速定位,從根節點開始定位查找;
找到后 再把這個索引關鍵字(就是我們的條件)存放的 磁盤文件地址拿到 .MYD 文件里面找,從而定位到索引所在行的記錄。
InnoDB
每個 MyISAM 表 都有 2個文件存儲在磁盤上。這些文件的 名稱 以 表名 開頭,以 擴展名 指示文件類型。
.frm
文件(frame)存儲表結構
;.ibd
文件(InnoDB Data)存儲表索引+數據
。
下面我創建了以 InnoDB 作為存儲引擎的一張表 t_user_innodb。
InnoDB 把 索引 和 數據 都放在了 同一個文件 里存著了。
毋庸置疑,InnoDB 表里面的數據也是用 B+tree 數據結構 組織起來的。 下面我們來看看它具體是怎么存儲的。
.ibd 存儲數據的特點就是 B+tree 的葉子節點上包括了: 索引 和 該索引所在 行 的 所有列數據 。
查找過程
首先會判斷查找條件 where 中的字段是否是索引字段,
如果是就會先拿著這字段去 .ibd 文件里通過 B+tree 快速定位,從根節點開始定位查找;
找到后直接把這個 索引關鍵字 及其記錄所在行的 所有列數據 返回。
相關拓展
聚集(聚簇)索引
聚集索引:葉子節點包含了 完整的 數據記錄。
簡單來說就是 索引 和它所在行的 其它列數據 全部都在一起了。很顯然,MyISAM 沒有聚集索引,InnoDB 有。
InnoDB 的 主鍵索引 就是天然的 聚集索引。
有 聚集索引 當然就有 非聚集索引(稀疏索引)。對于 MyISAM 來說,它的索引就是非聚集索引。因為它的索引和數據是分開兩個文件存的:一個 .MYI 存索引,一個 .MYD 存數據。
為什么 DBA 都建議表中一定要有主鍵,而且推薦使用整型自增?
為什么要有主鍵?
因為 InnoDB 表里面的數據必須要有一個 B+tree 的索引結構來組織、維護我們的整張表的所有數據,從而形成 .idb 文件。
那和主鍵有什么關系?
如果 InnoDB 創建了一張沒有主鍵的表,那這張表就有可能沒有任何索引,則 MySQL會選擇所有具有唯一性并且不為 null 中的第一個字段的創建聚集索引。
如果沒有唯一性索引的字段就會有一個隱式字段成為表的聚集索引:而這個隱式字段,就是 InnoDB 幫我們創建的一個長度為 6字節 的整數列 ROW_ID,它隨著新行的插入單調增加,InnoDB 就以該列對數據進行聚集。
使用這個 ROW_ID 列的表都共享一個相同的全局序列計數器(這是數據字典的一部分)。為了避免這個 ROW_ID 用完,所以建議表中一定要單獨建立一個主鍵字段。
為什么推薦使用整型自增?
首先整型的占用空間會比字符串小,而且在查找上比大小也會比字符串更快。字符串比大小的時候還要先轉換成 ASCII 碼再去比較。
如果使用自增的話,在插入方面的效率也會提高。
不使用自增,可能時不時會往 B+tree 的中間某一位置插入元素,當這個節點位置放滿了的時候,節點就要進行分裂操作(效率低)再去維護,有可能樹還要進行平衡,又是一個耗性能的操作。
都用自增就會永遠都往后面插入元素,這樣索引節點分裂的概率就會小很多。
二級索引
除聚集索引之外的所有索引都叫做二級索引,也稱輔助索引。
它的葉子節點 不會存儲 其它 所有列的數據,就只存儲 主鍵值。
優點:保持一致性和節省空間。