聊聊MySQL儲存引擎中索引如何落地?
theme: Chinese-red
小知識,大挑戰!本文正在參與“程式設計師必備小知識”創作活動。
我們知道不同的儲存引擎檔案是不一樣,我們可以檢視資料檔案目錄:
sql
show VARIABLES LIKE 'datadir';
每 張 InnoDB 的 表 有 兩 個 文 件 ( .frm 和 .ibd ),MyISAM 的 表 有 三 個 文 件 (.frm、.MYD、.MYI)。
有一個是相同的檔案,.frm
。.frm
是 MySQL 裡面表結構定義的檔案,不管你建表的時候選用任何一個儲存引擎都會生成,我們就不看了。
我們主要看一下其他兩個檔案是怎麼實現 MySQL 不同的儲存引擎的索引的。
我們先來看下 MyISAM。
MyISAM
在 MyISAM 裡面,另外有兩個檔案:
一個是.MYD
檔案,D 代表 Data,是 MyISAM 的資料檔案,存放資料記錄,比如我們的 user_myisam 表的所有的表資料。
一個是.MYI
檔案,I 代表 Index,是 MyISAM 的索引檔案,存放索引,比如我們在 id 欄位上面建立了一個主鍵索引,那麼主鍵索引就是在這個索引檔案裡面。
也就是說,在 MyISAM 裡面,索引和資料是兩個獨立的檔案。那我們怎麼根據索引找到資料呢?
MyISAM 的 B+Tree 裡面,葉子節點儲存的是資料檔案對應的磁碟地址。所以從索引檔案.MYI
中找到鍵值後,會到資料檔案.MYD
中獲取相應的資料記錄。
這裡畫的是主鍵索引,如果是輔助索引,有什麼不一樣呢?
在 MyISAM 裡面,輔助索引也在這個.MYI
檔案裡面。 輔助索引跟主鍵索引儲存和檢索資料的方式是沒有任何區別的,一樣是在索引檔案裡面找到磁碟地址,然後到資料檔案裡面獲取資料。
InnoDB
InnoDB 只有一個檔案(.ibd 檔案),那索引放在哪裡呢?
在 InnoDB 裡面,它是以主鍵為索引來組織資料的儲存的,所以索引檔案和資料檔案是同一個檔案,都在.ibd
檔案裡面。
在 InnoDB 的主鍵索引的葉子節點上,它直接儲存了我們的資料。
什麼叫做聚集索引(聚簇索引)?
就是索引鍵值的邏輯順序跟表資料行的物理儲存順序是一致的。(比如字典的目錄是按拼音排序的,內容也是按拼音排序的,按拼音排序的這種目錄就叫聚集索引)。
在 InnoDB 裡面,它組織資料的方式叫做叫做(聚集)索引組織表(clustered index organize table),所以主鍵索引是聚集索引,非主鍵都是非聚集索引。
主鍵之外的索引,比如我們在 name 欄位上面建的普通索引,又是怎麼儲存和檢索資料的呢?
InnoDB 中,主鍵索引和輔助索引是有一個主次之分的。
輔助索引儲存的是輔助索引和主鍵值。如果使用輔助索引查詢,會根據主鍵值在主鍵索引中查詢,最終取得資料。
比如我們用 name 索引查詢 name= '青山',它會在葉子節點找到主鍵值,也就是 id=1,然後再到主鍵索引的葉子節點拿到資料。
另一個問題,如果一張表沒有主鍵怎麼辦?
1、如果我們定義了主鍵(PRIMARY KEY),那麼 InnoDB 會選擇主鍵作為聚集索引。
2、如果沒有顯式定義主鍵,則 InnoDB 會選擇第一個不包含有 NULL 值的唯一索引作為主鍵索引。
3、如果也沒有這樣的唯一索引,則 InnoDB 會選擇內建 6 位元組長的 ROWID 作為隱藏的聚集索引,它會隨著行記錄的寫入而主鍵遞增。
sql
select _rowid name from t2;
所以呢?不會存在沒有主鍵的表。
小結
通過以上的分析,我們知道在 MyISAM 和 InnoDB 這兩大儲存引擎中,索引的具體落地形式是怎麼樣的。
看完如果覺得文章對你有點幫助,歡迎點贊、評論加關注。在下感謝各位的點贊關注。
- 一文弄懂Java中執行緒池原理
- 聊聊工作中,如何提升自己的程式設計能力?
- 聊聊MQ,如何避免訊息丟失?如何避免重複消費?
- Java實現串列埠通訊
- SpringBoot為什麼可以使用Jar包啟動?
- 2021,平凡的一年!
- 聊聊 Java 中引數傳遞的原理!
- 聊聊Pulsar,一款非常優秀的訊息中介軟體!!!
- 乾貨,聊聊Java中String類!!!
- 萬字!Java相關的學習資料整理(乾貨滿滿)
- 使用 ArrayList 應當避免的坑
- Java中避免空指標的幾個方法!
- 聊聊Jhipster,強烈推薦Java開發看看,節省很多時間!!!
- 給程式設計師新手的一些建議
- 計算機基礎知識:磁碟分割槽
- Java中的序列化
- Java中的控制流程語句詳解
- 程式設計師必備:Git入門,超詳細
- netty系列:使用 SSL/TLS 加密 Netty 程式
- 聊聊MySQL儲存引擎中索引如何落地?