搜尋
首頁資料庫mysql教程InnoDB的資料儲存檔案和MyISAM的不同

MySQL教學欄位介紹的索引為什麼用B Tree

InnoDB的資料儲存檔案和MyISAM的不同

##前言

這篇文章的題目,是我真實在面試過程中遇到的問題,某網路群眾募資公司在檢視面試者MySQL相關知識的第一個問題,我當時還是比較懵的,沒想到這年輕人不講武德,不按套路出牌,一般的問MySQL的相關知識的時候,不都是問索引優化以及索引失效等相關問題嗎?怎麼還出來了,儲存檔案的不同?就算考察個MVCC機制也行啊。所以這次我就好好總結總結這部分知識點。

為什麼需要建立索引

首先,我們都知道建立索引的目的是為了提高查詢速度,那麼為什麼有了索引就能提高查詢速度呢?

我們來看一下,一個索引的示意圖。

如果我有一個SQL語句是:
select * from Table where id = 15 那麼在沒有索引的情況下其實是會進行全表掃描的,就是挨個去找,直到找到id=15的這條記錄,時間複雜度是O(n);

如果在有索引的情況下去進行查詢呢。首先會根據id=15,在索引值裡面進行二分查找,二分查找的效率是很高的,它的時間複雜度是O(logn);

這就是索引為什麼能提高查詢效率了,但是索引資料的量也是比較大的,所以一般並不是儲存在記憶體中的,都是直接儲存在磁碟中的,所以對磁碟中的檔案內容進行讀取,免不了要進行磁碟IO。

MySQL的索引為什麼要使用B Tree

上面我們也說了,索引資料一般是儲存在磁碟中的,但是計算資料都是要在記憶體中進行的,如果索引檔案很大的話,並不能一次都載入進內存,所以在使用索引進行資料查找的時候是會進行多次磁碟IO,將索引資料分批的載入到記憶體中,

因此一個好的索引的資料結構,在得到正確的結果前提下,一定是磁碟IO次數最少的。 <strong></strong>

Hash型別

目前MySQL其實是有兩種索引資料型別可以選擇的,一個是BTree(實際上是B Tree)、一個Hash。

但是為什麼在實際的使用過程中,基本上大部分都是選擇BTree呢?

因為如果使用Hash類型的索引,MySQL在創建索引的時候,會對索引資料進行一次Hash運算,這樣根據Hash值就能快速的定位到磁碟指標了,就算資料量很大,也能快速精準的定位到數據。

    但是像
  • select * from Table where id > 15這種範圍查詢,Hash類型的索引就搞不定了,對這種範圍查詢,會直接全表掃描,另外Hash類型的索引也搞不定排序。
  • 還有就是雖然MySQL底層做了一系列的處理,但還是不能完全的保證,不產生Hash碰撞。

二元樹

那MySQL為什麼沒有二元樹作為它的索引資料結構呢?我們都知道,二元樹是透過二分查找來進行定位資料的,所以效果還是不錯的,時間複雜度是O(logn);


InnoDB的資料儲存檔案和MyISAM的不同 但是二元樹有個問題,就是在特殊情況下,它會退化成一根棍子,也就是單向鍊錶。這時候,它的時間複雜度就會退化成O(n);

InnoDB的資料儲存檔案和MyISAM的不同退化成链表 所以當我們要查詢id=50的記錄時,其實跟全表掃描是一樣的了。所以因為有這種情況,二元樹不適合作為索引的資料結構。

平衡二元樹

那麼既然二元樹,在特殊情況下會退化成鍊錶,那麼平衡二元樹為什麼不行呢?

平衡二元樹的子節點高度差不能超過1,像下圖中的二元樹,關鍵字為15的節點,它的左子節點高度為0,右子節點高度為1,高度差不超過1,所以下面這棵樹是一棵平衡二元樹。
平衡InnoDB的資料儲存檔案和MyISAM的不同 因為能保持平衡,所以它的查詢時間複雜度為O(logN),至於怎麼保持平衡的,主要是做一些左旋,右旋等,具體保持平衡的細節不是本文主要內容,想了解的可自行搜尋。

用這個資料結構來做MySQL的索引會有 什麼問題呢?

  • 磁碟IO過多:在MySQL當中,一次IO操作只讀取一個節點,那麼一個節點若是最多就兩個子節點的話,那就只有這兩個子節點的查詢範圍,所以要精確到具體的資料時,就需要進行多次讀取,如果樹非常深的話,那麼將會進行大量的磁碟IO。性能自然下降了。
  • 空間利用率低:對於平衡二元樹來說,每個節點值保存一個關鍵字,一個資料區,兩個子節點的指標。這樣導致了,一次辛苦的IO操作就只載入這麼點數據,實在是有點殺雞用牛刀了。
  • 查詢效果不穩定:如果在一個高度很深的平衡二元樹中,若是查詢的資料正好是根節點,那麼就會很快的查到,若是查詢的數據正好是葉子節點,那麼會進行多次磁碟IO後才能返回,回應時間有可能和根節點的不在一個數量級上。

雖然說二元樹解決的平衡的問題,但是也帶來了新的問題,那就是由於它本身樹的深度的,會造成一系列的效率問題。

那麼為了解決平衡二元樹的這類問題,平衡多叉樹(Balance Tree)就成為了更好的選擇。

平衡多叉樹(Balance Tree–B-Tree)

B-Tree的意思是平衡多叉樹,一般B-Tree中的一個節點有多少個子節點,我們就稱為多少階的B-Tree。通常用m表示階數,當m為2的時候,就是平衡二元樹。

一棵B-Tree的每個節點上最多能有m-1個關鍵字,最少要存放Math.ceil(m/2)-1個關鍵字,所有的葉子節點都在同一層。如下圖就是一個4階的B-Tree。
InnoDB的資料儲存檔案和MyISAM的不同
那麼我們來看B-Tree是如何進行查找數據的

  • 若是查詢id=7的數據,先將關鍵字20的節點載入進內存,判斷出7比20小;
  • 那麼載入第一個子節點,若查詢的資料等於12或17則直接返回,不等於就繼續向下找,發現7小於12;
  • 那麼繼續載入第一個子節點中去,找到7之後,直接將7下面的data資料回傳。

這樣整個操作其實進行了3次IO操作,但實際上一般的B-Tree每層都是有很多分支(通常都大於100)。

MySQL為了能更好的利用磁碟的IO能力,將操作頁的大小設定為了16K,即每個節點的大小為16K。如果每個節點中的關鍵字都是int類型的,那麼就是4個字節,若資料區的大小為8個字節,節點指標再佔4個字節,那麼B-Tree的每個節點中可以儲存的關鍵字個數為:(16*1000) / (4 8 4)=1000,每個節點最多可儲存1000個關鍵字,每個節點最多可以有1001個分支節點。

這樣在查詢索引資料的時候,一次磁碟IO操作可以將1000個關鍵字,讀取到記憶體中進行計算,B-Tree的一次磁碟IO的操作,頂上平衡二叉資料的N次磁碟IO操作了。

要注意的是B-Tree為了確保資料的平衡,會做一系列的操作,這個保持平衡的過程比較耗時間,所以在建立索引的時候,要選擇合適的字段,並且不要過多的創建索引,創建索引過多的話,在更新資料的時候,更新索引的過程也比較耗時。

還有就是不要選擇低區分度字段值作為索引,例如性別字段,總共就兩個值,那麼就有可能會造成B-Tree的深度過大,索引效率降低。

B Tree

B-Tree已經很好的解決平衡二元樹的問題了,並且也能保證查詢效率了,那麼為什麼會有B Tree呢?

我們先來B Tree是什麼樣子的。

B Tree是B-Tree的變種,B Tree的每個節點關鍵字和m階的公式關係和B-Tree的不一樣了。

首先每個節點的子節點數量和每個節點可儲存的關鍵字比例是1:1,其次就是查詢資料的時候採用的是左閉合區間進行查詢,還有就是分支節點中沒有資料了只保存關鍵字和子節點指向,資料都儲存在葉子節點。
InnoDB的資料儲存檔案和MyISAM的不同
那麼來看看在B Tree中是如何進行資料查詢的。

例如:

  • 現在要查詢id=2的數據,那麼會先將根節點取出,載入到記憶體中,發現id=2存在於根節點,因為是左閉合區間儲存數據,所以id的都在根節點的第一個子節點上;
  • 那麼取出第一個子節點,載入到記憶體中,發現目前節點存在id=2的關鍵字,而且已經到了葉子節點了,那麼直接取出葉子節點中的資料回傳。

現在來看B-Tree和B Tree的區別

  • B Tree的查詢所採用的左閉合區間,這樣能更好的支援了自增索引的查詢效果,所以一般在創建主鍵的時候通常都是自增的。這一點和B-Tree是不一樣的。
  • B Tree中的根節點和分支節點上是不保存資料的,關鍵字相關的資料只保存在葉子節點上,這樣保證了查詢效果的穩定,任何查詢都要走到葉子節點才能取得資料。而B-Tree在分支節點中保存了數據,若是命中關鍵字則直接回傳數據。
  • B Tree的葉子節點是順序排列的,並且相鄰的兩個葉子節點中具有順序引用的關係,這樣能更好的支援了範圍查詢。而B-Tree是沒有這個順序關係的。

MySQL的索引為什麼選擇了B Tree

經過上面的層層分析,現在我們可以總結一下MySQL為什麼選擇了B Tree作為它索引的資料結構呢。

  1. 首先和平衡二元樹相比,B Tree的深度更低,節點保存關鍵字更多,磁碟IO次數更少,查詢計算效率更好。

  2. B Tree的全域掃描能力更強,若是想根據索引資料對資料表進行全域掃描,B-Tree會將整棵樹進行掃描,然後逐層遍歷。而B Tree呢,只需要遍歷葉子節點即可,因為葉子節點之間存在著順序引用的關係。

  3. B Tree的磁碟IO讀寫能力更強,因為B Tree的每個分支節點上只保存了關鍵字,這樣每次磁碟IO在讀寫的時候,一頁16K資料量可以儲存更多的關鍵字了,每個節點上保存的關鍵字也比B-Tree更多了。這樣B Tree的一次磁碟IO載入的資料比B-Tree的多很多了。

  4. B Tree資料結構中有天然的排序能力,比其他資料結構排序能力更強而且排序時,是透過分支節點來進行的,若是需要將分支節點載入到記憶體排序,一次載入的資料更多。

  5. B Tree的查詢效果更穩定,因為所有的查詢都是需要掃描到葉子節點才傳回資料的。效果只是穩定而不一定是最優,若是直接查詢B-Tree的根節點數據,那麼B-Tree只需要一次磁碟IO就可以直接將數據傳回,反而是效果最優。

經過以上幾點的分析,MySQL最後選擇了B Tree作為了它的索引的資料結構。

InnDB的資料儲存檔案和MyISAM的有何不同?

上面總結了MySQL的索引的資料結構,這次就可以說第二個問題了,因為這個問題其實和MySQL的索引還是有一定的關係的。
下面來看看,先找到伺服器桑MySQL儲存資料的目錄:
登入MySQL,開啟MySQL的命令列介面:輸入show variables like '�tadir%';,就能看到儲存資料的目錄了。
我的伺服器中MySQL的儲存資料的目錄是在:

/var/lib/mysql/

進入這個目錄後,可以看到所有資料庫的目錄,新建一個study_test的資料庫。
然後就進入

/var/lib/mysql/study_test

這個目錄下,目前就只有一個文件,這個文件是用來記錄創建資料庫時配置的字元集的內容。

-rw-r----- 1 mysql mysql     60 1月  31 10:28 db.opt

現在新建兩個表,第一個表的引擎類型選擇InnoDB,第二個表的引擎類型選擇MyISAM。

student_innodb

CREATE TABLE `student_innodb` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `address` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE COMMENT 'name索引') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='innodb引擎表';

student_myisam

CREATE TABLE `student_myisam` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `address` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE COMMENT 'name索引') ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='myISAM引擎类型表';

將兩個表格建立完成後,我們再進入 #/var/lib/mysql/study_test看一下:

-rw-r----- 1 mysql mysql     60 1月  31 10:28 db.opt-rw-r----- 1 mysql mysql   8650 1月  31 10:41 student_innodb.frm-rw-r----- 1 mysql mysql 114688 1月  31 10:41 student_innodb.ibd-rw-r----- 1 mysql mysql   8650 1月  31 10:58 student_myisam.frm-rw-r----- 1 mysql mysql      0 1月  31 10:58 student_myisam.MYD-rw-r----- 1 mysql mysql   1024 1月  31 10:58 student_myisam.MYI

透過目錄中的文件可看到創建表之後多了幾個文件,這樣也看出來了,InnoDB引擎類型的表和MyISAM引擎類型的表的文件差異。

這幾個文件每個都是有自己的作用:

  • InnoDB引擎的表文件,一共有兩個:
    • *.frm 這類文件是表的定義檔。
    • *.ibd 這類檔案是資料和索引儲存檔案。表資料和索引聚集存儲,透過索引能直接查詢到資料。
  • MyIASM引擎的表文件,一共有三個:
    • *.frm 這類文件是表格的定義檔。
    • *.MYD 這類文件是表格資料文件,表中的所有資料都保存在此文件中。
    • *.MYI 這類文件是表的索引文件,MyISAM儲存引擎的索引資料單獨儲存。

MyISAM資料儲存引擎,索引與資料的儲存結構

MyISAM儲存引擎在儲存索引的時候,就是將索引資料是單獨存儲,並且索引的B Tree最終指向的是資料存在的實體位址,而不是特定的資料。然後再根據實體位址去資料檔(*.MYD)中找到具體的資料。

如下圖所示:
InnoDB的資料儲存檔案和MyISAM的不同
那麼當存在多個索引時,多個索引都指向相同的實體位址。
如下圖:
InnoDB的資料儲存檔案和MyISAM的不同
透過這個結構,我們可以看出來,MyISAM的儲存引擎的索引都是同層級的,主鍵和非主鍵索引結構和查詢方式完全一樣。

InnoDB資料儲存引擎,索引與資料的儲存結構

首先InnoDB的索引分為叢集索引和非叢集索引,叢集索引即保存關鍵字又保存數據,在B Tree的每個分支節點上保存關鍵字,葉子節點上保存數據。
聚簇”的意思是資料行被依照一定順序一個個緊密地排列在一起儲存。一個表格只能有一個叢集索引,因為在一個表格中資料的存放方式只有一種,一般是主鍵作為叢集索引,如果沒有主鍵,InnoDB會預設產生一個隱藏的資料列作為主鍵。

如下圖所示:
InnoDB的資料儲存檔案和MyISAM的不同
非聚集索引,又稱為二級索引,雖然也是在B Tree的每個分支節點上保存關鍵字,但是葉子節點不是保存的數據,而是保存的主鍵值。透過二級索引去查詢資料會先查詢到資料對應的主鍵,然後再根據主鍵查詢到特定的資料行。

如下圖所示:
InnoDB的資料儲存檔案和MyISAM的不同
由於非聚集索引的設計結構,導致了,非叢集索引在查詢的時候要進行兩次索引檢索,這樣設計的好處,可以保證了一旦發生資料遷移的時候,只需要更新主鍵索引即可,非聚簇索引並不用動,而且也規避了像MyISAM的索引那樣存儲物理地址,在資料遷移的時候的需要重新維護所有索引的問題。

總結

這次把MySQL的索引的資料結構,以及檔案儲存結構,總結清楚了,後面在實際的工作過程中,設計索引的時候能夠考慮的更全了,透過了解了索引的資料結構,也能讓自己在實際寫SQL的時候,能考慮到哪些情況走索引哪些不走索引了。

  • MySQL使用B Tree作為索引的資料結構,因為B Tree的深度低,節點保存的關鍵字多,磁碟IO次數少,從而保證了查詢效率更高。
  • B Tree能夠保證MySQL無論是主鍵索引還是非主鍵索引的查詢效果都是穩定的,每次都要查詢到葉子節點才能返回數據,B Tree的葉子節點的深度是一樣的,而且為了更好的支援自增主鍵,B Tree的查詢節點範圍是左閉合右開放。
  • MySQL的MyISAM儲存引擎,表格資料索引資料是分別放到兩個檔案中進行儲存的,由於它本身的索引的B Tree的葉子節點指向的表資料所在的磁碟位址,而且索引沒有主鍵和非主鍵之分,所以分開存儲,能夠更好的統一管理索引;
  • MySQL的InnoDB儲存引擎,表數據索引資料是儲存在一個檔案中的,因為InnoDB的叢集索引的葉子節點指向的具體的資料行,而且為了保證查詢效果的穩定,InnoDB表中必須要有一個聚集索引,二級索引在進行索引檢索時,會先透過二級索引檢索到資料的主鍵值,再根據主鍵去叢集索引中檢索到特定的資料。

相關免費學習推薦:mysql影片教學

以上是InnoDB的資料儲存檔案和MyISAM的不同的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
MySQL的位置:數據庫和編程MySQL的位置:數據庫和編程Apr 13, 2025 am 12:18 AM

MySQL在數據庫和編程中的地位非常重要,它是一個開源的關係型數據庫管理系統,廣泛應用於各種應用場景。 1)MySQL提供高效的數據存儲、組織和檢索功能,支持Web、移動和企業級系統。 2)它使用客戶端-服務器架構,支持多種存儲引擎和索引優化。 3)基本用法包括創建表和插入數據,高級用法涉及多表JOIN和復雜查詢。 4)常見問題如SQL語法錯誤和性能問題可以通過EXPLAIN命令和慢查詢日誌調試。 5)性能優化方法包括合理使用索引、優化查詢和使用緩存,最佳實踐包括使用事務和PreparedStatemen

MySQL:從小型企業到大型企業MySQL:從小型企業到大型企業Apr 13, 2025 am 12:17 AM

MySQL適合小型和大型企業。 1)小型企業可使用MySQL進行基本數據管理,如存儲客戶信息。 2)大型企業可利用MySQL處理海量數據和復雜業務邏輯,優化查詢性能和事務處理。

幻影是什麼讀取的,InnoDB如何阻止它們(下一個鍵鎖定)?幻影是什麼讀取的,InnoDB如何阻止它們(下一個鍵鎖定)?Apr 13, 2025 am 12:16 AM

InnoDB通過Next-KeyLocking機制有效防止幻讀。 1)Next-KeyLocking結合行鎖和間隙鎖,鎖定記錄及其間隙,防止新記錄插入。 2)在實際應用中,通過優化查詢和調整隔離級別,可以減少鎖競爭,提高並發性能。

mysql:不是編程語言,而是...mysql:不是編程語言,而是...Apr 13, 2025 am 12:03 AM

MySQL不是一門編程語言,但其查詢語言SQL具備編程語言的特性:1.SQL支持條件判斷、循環和變量操作;2.通過存儲過程、觸發器和函數,用戶可以在數據庫中執行複雜邏輯操作。

MySQL:世界上最受歡迎的數據庫的簡介MySQL:世界上最受歡迎的數據庫的簡介Apr 12, 2025 am 12:18 AM

MySQL是一種開源的關係型數據庫管理系統,主要用於快速、可靠地存儲和檢索數據。其工作原理包括客戶端請求、查詢解析、執行查詢和返回結果。使用示例包括創建表、插入和查詢數據,以及高級功能如JOIN操作。常見錯誤涉及SQL語法、數據類型和權限問題,優化建議包括使用索引、優化查詢和分錶分區。

MySQL的重要性:數據存儲和管理MySQL的重要性:數據存儲和管理Apr 12, 2025 am 12:18 AM

MySQL是一個開源的關係型數據庫管理系統,適用於數據存儲、管理、查詢和安全。 1.它支持多種操作系統,廣泛應用於Web應用等領域。 2.通過客戶端-服務器架構和不同存儲引擎,MySQL高效處理數據。 3.基本用法包括創建數據庫和表,插入、查詢和更新數據。 4.高級用法涉及復雜查詢和存儲過程。 5.常見錯誤可通過EXPLAIN語句調試。 6.性能優化包括合理使用索引和優化查詢語句。

為什麼要使用mysql?利益和優勢為什麼要使用mysql?利益和優勢Apr 12, 2025 am 12:17 AM

選擇MySQL的原因是其性能、可靠性、易用性和社區支持。 1.MySQL提供高效的數據存儲和檢索功能,支持多種數據類型和高級查詢操作。 2.採用客戶端-服務器架構和多種存儲引擎,支持事務和查詢優化。 3.易於使用,支持多種操作系統和編程語言。 4.擁有強大的社區支持,提供豐富的資源和解決方案。

描述InnoDB鎖定機制(共享鎖,獨家鎖,意向鎖,記錄鎖,間隙鎖,下一鍵鎖)。描述InnoDB鎖定機制(共享鎖,獨家鎖,意向鎖,記錄鎖,間隙鎖,下一鍵鎖)。Apr 12, 2025 am 12:16 AM

InnoDB的鎖機制包括共享鎖、排他鎖、意向鎖、記錄鎖、間隙鎖和下一個鍵鎖。 1.共享鎖允許事務讀取數據而不阻止其他事務讀取。 2.排他鎖阻止其他事務讀取和修改數據。 3.意向鎖優化鎖效率。 4.記錄鎖鎖定索引記錄。 5.間隙鎖鎖定索引記錄間隙。 6.下一個鍵鎖是記錄鎖和間隙鎖的組合,確保數據一致性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具