溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些

發(fā)布時(shí)間:2021-02-23 13:55:30 來源:億速云 閱讀:214 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章將為大家詳細(xì)講解有關(guān)InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

為什么需要建立索引

首先,我們都知道建立索引的目的是為了提高查詢速度,那么為什么有了索引就能提高查詢速度呢?
我們來看一下,一個(gè)索引的示意圖。
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
如果我有一個(gè)SQL語句是:select * from Table where id = 15 那么在沒有索引的情況下其實(shí)是會(huì)進(jìn)行全表掃描的,就是挨個(gè)去找,直到找到id=15的這條記錄,時(shí)間復(fù)雜度是O(n);

如果在有索引的情況下去進(jìn)行查詢呢。首先會(huì)根據(jù)id=15,在索引值里面進(jìn)行二分查找,二分查找的效率是很高的,它的時(shí)間復(fù)雜度是O(logn);

這就是索引為什么能提高查詢效率了,但是索引數(shù)據(jù)的量也是比較大的,所以一般并不是存儲(chǔ)在內(nèi)存中的,都是直接存儲(chǔ)在磁盤中的,所以對(duì)磁盤中的文件內(nèi)容進(jìn)行讀取,免不了要進(jìn)行磁盤IO。

MySQL的索引為什么使用B+Tree

上面我們也說了,索引數(shù)據(jù)一般是存儲(chǔ)在磁盤中的,但是計(jì)算數(shù)據(jù)都是要在內(nèi)存中進(jìn)行的,如果索引文件很大的話,并不能一次都加載進(jìn)內(nèi)存,所以在使用索引進(jìn)行數(shù)據(jù)查找的時(shí)候是會(huì)進(jìn)行多次磁盤IO,將索引數(shù)據(jù)分批的加載到內(nèi)存中,因此一個(gè)好的索引的數(shù)據(jù)結(jié)構(gòu),在得到正確的結(jié)果前提下,一定是磁盤IO次數(shù)最少的。

Hash類型

目前MySQL其實(shí)是有兩種索引數(shù)據(jù)類型可以選擇的,一個(gè)是BTree(實(shí)際是B+Tree)、一個(gè)Hash。

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

因?yàn)槿绻褂肏ash類型的索引,MySQL在創(chuàng)建索引的時(shí)候,會(huì)對(duì)索引數(shù)據(jù)進(jìn)行一次Hash運(yùn)算,這樣根據(jù)Hash值就能快速的定位到磁盤指針了,就算數(shù)據(jù)量很大,也能快速精準(zhǔn)的定位到數(shù)據(jù)。

  • 但是像select * from Table where id > 15這種范圍查詢,Hash類型的索引就搞不定了,對(duì)這種范圍查詢,會(huì)直接全表掃描,另外Hash類型的索引也搞不定排序。

  • 還有就是雖然MySQL底層做了一系列的處理,但還是不能完全的保證,不產(chǎn)生Hash碰撞。

二叉樹

那MySQL為什么沒有二叉樹作為它的索引數(shù)據(jù)結(jié)構(gòu)呢?我們都知道,二叉樹是通過二分查找來進(jìn)行定位數(shù)據(jù)的,所以效果還是不錯(cuò)的,時(shí)間復(fù)雜度是O(logn);
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
但是二叉樹有個(gè)問題,就是在特殊情況下,它會(huì)退化成一根棍子,也就是一個(gè)單向鏈表。這個(gè)時(shí)候,它的時(shí)間復(fù)雜度就會(huì)退化成O(n);
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
所以當(dāng)我們要查詢id=50的記錄時(shí),其實(shí)和全表掃描是一樣的了。所以因?yàn)榇嬖谶@種情況,二叉樹不適合作為索引的數(shù)據(jù)結(jié)構(gòu)。

平衡二叉樹

那么既然二叉樹,在特殊情況下會(huì)退化成鏈表,那么平衡二叉樹為什么不可以呢?

平衡二叉樹的子節(jié)點(diǎn)高度差不能超過1,像下圖中的二叉樹,關(guān)鍵字為15的節(jié)點(diǎn),它的左子節(jié)點(diǎn)高度為0,右子節(jié)點(diǎn)高度為1,高度差不超過1,所以下面這棵樹是一棵平衡二叉樹。
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
因?yàn)槟鼙3制胶猓运牟樵儠r(shí)間復(fù)雜度為O(logN),至于怎么保持平衡的,主要是做一些左旋,右旋等,具體保持平衡的細(xì)節(jié)不是本文主要內(nèi)容,想了解的可自行搜索。

用這個(gè)數(shù)據(jù)結(jié)構(gòu)來做MySQL的索引會(huì)有 什么問題呢?

  • 磁盤IO過多:在MySQL當(dāng)中,一次IO操作只讀取一個(gè)節(jié)點(diǎn),那么一個(gè)節(jié)點(diǎn)若是最多就兩個(gè)子節(jié)點(diǎn)的話,那么就只有這兩個(gè)子節(jié)點(diǎn)的查詢范圍,所以要精確到具體的數(shù)據(jù)時(shí),就需要進(jìn)行多次讀取,如果樹非常深的話,那么將會(huì)進(jìn)行大量的磁盤IO。性能自然下降了。

  • 空間利用率低:對(duì)于平衡二叉樹來說,每個(gè)節(jié)點(diǎn)值保存一個(gè)關(guān)鍵字,一個(gè)數(shù)據(jù)區(qū),兩個(gè)子節(jié)點(diǎn)的指針。這樣導(dǎo)致了,一次辛辛苦苦的IO操作就只加載這么點(diǎn)數(shù)據(jù),實(shí)在是有點(diǎn)殺雞用牛刀了。

  • 查詢效果不穩(wěn)定:如果在一個(gè)高度很深的平衡二叉樹中,若是查詢的數(shù)據(jù)正好是根節(jié)點(diǎn),那么就會(huì)很快的查到,若是查詢的數(shù)據(jù)正好是葉子節(jié)點(diǎn),那么會(huì)進(jìn)行多次磁盤IO后才能返回,響應(yīng)時(shí)間有可能和根節(jié)點(diǎn)的不在一個(gè)數(shù)量級(jí)上。

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

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

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

B-Tree的意思是平衡多叉樹,一般B-Tree中的一個(gè)節(jié)點(diǎn)有多少個(gè)子節(jié)點(diǎn),我們就稱為多少階的B-Tree。通常用m表示階數(shù),當(dāng)m為2的時(shí)候,就是平衡二叉樹。

一棵B-Tree的每個(gè)節(jié)點(diǎn)上最多能有m-1個(gè)關(guān)鍵字,最少要存放Math.ceil(m/2)-1個(gè)關(guān)鍵字,所有的葉子節(jié)點(diǎn)都在同一層。如下圖就是一個(gè)4階的B-Tree。
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
那么我們看一下B-Tree是如何進(jìn)行查找數(shù)據(jù)的

  • 若是查詢id=7的數(shù)據(jù),先將關(guān)鍵字20的節(jié)點(diǎn)加載進(jìn)內(nèi)存,判斷出7比20?。?/p>

  • 那么加載第一個(gè)子節(jié)點(diǎn),若查詢的數(shù)據(jù)等于12或17則直接返回,不等于就繼續(xù)向下找,發(fā)現(xiàn)7小于12;

  • 那么繼續(xù)加載第一個(gè)子節(jié)點(diǎn)中去,找到7之后,直接將7下面的data數(shù)據(jù)返回。

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

MySQL為了能更好的利用磁盤的IO能力,將操作頁的大小設(shè)置為了16K,即每個(gè)節(jié)點(diǎn)的大小為16K。如果每個(gè)節(jié)點(diǎn)中的關(guān)鍵字都是int類型的,那么就是4個(gè)字節(jié),若數(shù)據(jù)區(qū)的大小為8個(gè)字節(jié),節(jié)點(diǎn)指針再占4個(gè)字節(jié),那么B-Tree的每個(gè)節(jié)點(diǎn)中可以保存的關(guān)鍵字個(gè)數(shù)為:(16*1000) / (4+8+4)=1000,每個(gè)節(jié)點(diǎn)最多可存儲(chǔ)1000個(gè)關(guān)鍵字,每一個(gè)節(jié)點(diǎn)最多可以有1001個(gè)分支節(jié)點(diǎn)。

這樣在查詢索引數(shù)據(jù)的時(shí)候,一次磁盤IO操作可以將1000個(gè)關(guān)鍵字,讀取到內(nèi)存中進(jìn)行計(jì)算,B-Tree的一次磁盤IO的操作,頂上平衡二叉數(shù)據(jù)的N次磁盤IO操作了。

要注意的是B-Tree為了保證數(shù)據(jù)的平衡,會(huì)做一系列的操作,這個(gè)保持平衡的過程比較耗時(shí)間,所以在創(chuàng)建索引的時(shí)候,要選擇合適的字段,并且不要過多的創(chuàng)建索引,創(chuàng)建索引過多的話,在更新數(shù)據(jù)的時(shí)候,更新索引的過程也比較耗時(shí)。

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

B+Tree

B-Tree已經(jīng)很好的解決平衡二叉樹的問題了,并且也能保證查詢效率了,那么為什么會(huì)有B+Tree呢?

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

B+Tree是B-Tree的變種,B+Tree的每個(gè)節(jié)點(diǎn)關(guān)鍵字和m階的公式關(guān)系和B-Tree的不一樣了。

首先每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)數(shù)量和每個(gè)節(jié)點(diǎn)可存儲(chǔ)的關(guān)鍵字比例是1:1,其次就是查詢數(shù)據(jù)的時(shí)候采用的是左閉合區(qū)間進(jìn)行查詢,還有就是分支節(jié)點(diǎn)中沒有數(shù)據(jù)了只保存關(guān)鍵字和子節(jié)點(diǎn)指向,數(shù)據(jù)都存儲(chǔ)在葉子節(jié)點(diǎn)。
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
那么來看一下在B+Tree中是如何進(jìn)行數(shù)據(jù)查詢的。

例如:

  • 現(xiàn)在要查詢id=2的數(shù)據(jù),那么會(huì)先將根節(jié)點(diǎn)取出,加載到內(nèi)存中,發(fā)現(xiàn)id=2存在于根節(jié)點(diǎn),因?yàn)槭亲箝]合區(qū)間存儲(chǔ)數(shù)據(jù),所以id<=2的都在根節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)上;

  • 那么取出第一個(gè)子節(jié)點(diǎn),加載到內(nèi)存中,發(fā)現(xiàn)當(dāng)前節(jié)點(diǎn)存在id=2的關(guān)鍵字,并且已經(jīng)到了葉子節(jié)點(diǎn)了,那么直接取出葉子節(jié)點(diǎn)中的數(shù)據(jù)返回。

現(xiàn)在來看一下B-Tree和B+Tree的區(qū)別

  • B+Tree的查詢采用的左閉合區(qū)間,這樣能更好的支持了自增索引的查詢效果,所以一般在創(chuàng)建主鍵的時(shí)候通常都是自增的。這一點(diǎn)和B-Tree是不一樣的。

  • B+Tree中的根節(jié)點(diǎn)和分支節(jié)點(diǎn)上是不保存數(shù)據(jù)的,關(guān)鍵字相關(guān)的數(shù)據(jù)只保存在葉子節(jié)點(diǎn)上,這樣保證了查詢效果的穩(wěn)定,任何查詢都要走到葉子節(jié)點(diǎn)才能獲取數(shù)據(jù)。而B-Tree在分支節(jié)點(diǎn)中保存了數(shù)據(jù),若是命中關(guān)鍵字則直接返回?cái)?shù)據(jù)。

  • B+Tree的葉子節(jié)點(diǎn)是順序排列的,并且相鄰的兩個(gè)葉子節(jié)點(diǎn)中具有順序引用的關(guān)系,這樣能更好的支持了范圍查詢。而B-Tree是沒有這個(gè)順序關(guān)系的。

MySQL的索引為什么選擇了B+Tree

經(jīng)過上面的層層分析,現(xiàn)在我們可以總結(jié)一下MySQL為什么選擇了B+Tree作為它索引的數(shù)據(jù)結(jié)構(gòu)呢。

  1. 首先和平衡二叉樹相比,B+Tree的深度更低,節(jié)點(diǎn)保存關(guān)鍵字更多,磁盤IO次數(shù)更少,查詢計(jì)算效率更好。

  2. B+Tree的全局掃描能力更強(qiáng),若是想根據(jù)索引數(shù)據(jù)對(duì)數(shù)據(jù)表進(jìn)行全局掃描,B-Tree會(huì)將整棵樹進(jìn)行掃描,然后逐層遍歷。而B+Tree呢,只需要遍歷葉子節(jié)點(diǎn)即可,因?yàn)槿~子節(jié)點(diǎn)之間存在順序引用的關(guān)系。

  3. B+Tree的磁盤IO讀寫能力更強(qiáng),因?yàn)锽+Tree的每個(gè)分支節(jié)點(diǎn)上只保存了關(guān)鍵字,這樣每次磁盤IO在讀寫的時(shí)候,一頁16K數(shù)據(jù)量可以存儲(chǔ)更多的關(guān)鍵字了,每個(gè)節(jié)點(diǎn)上保存的關(guān)鍵字也比B-Tree更多了。這樣B+Tree的一次磁盤IO加載的數(shù)據(jù)比B-Tree的多很多了。

  4. B+Tree數(shù)據(jù)結(jié)構(gòu)中有天然的排序能力,比其他數(shù)據(jù)結(jié)構(gòu)排序能力更強(qiáng)而且排序時(shí),是通過分支節(jié)點(diǎn)來進(jìn)行的,若是需要將分支節(jié)點(diǎn)加載到內(nèi)存中排序,一次加載的數(shù)據(jù)更多。

  5. B+Tree的查詢效果更穩(wěn)定,因?yàn)樗械牟樵兌际切枰獟呙璧饺~子節(jié)點(diǎn)才將數(shù)據(jù)返回的。效果只是穩(wěn)定而不一定是最優(yōu),若是直接查詢B-Tree的根節(jié)點(diǎn)數(shù)據(jù),那么B-Tree只需要一次磁盤IO就可以直接將數(shù)據(jù)返回,反而是效果最優(yōu)。

經(jīng)過以上幾點(diǎn)的分析,MySQL最終選擇了B+Tree作為了它的索引的數(shù)據(jù)結(jié)構(gòu)。

InnDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的有何不同?

上面總結(jié)了MySQL的索引的數(shù)據(jù)結(jié)構(gòu),這次就可以說第二個(gè)問題了,因?yàn)檫@個(gè)問題其實(shí)和MySQL的索引還是有一定的關(guān)系的。
下面來看一下,先找到服務(wù)器桑MySQL存儲(chǔ)數(shù)據(jù)的目錄:
登錄MySQL,打開MySQL的命令行界面:輸入show variables like '%datadir%';,就能看到存儲(chǔ)數(shù)據(jù)的目錄了。
我的服務(wù)器中MySQL的存儲(chǔ)數(shù)據(jù)的目錄是在:

/var/lib/mysql/

進(jìn)入到這個(gè)目錄里后,能看到所有數(shù)據(jù)庫的目錄,新建一個(gè)study_test的數(shù)據(jù)庫。
然后就進(jìn)入

/var/lib/mysql/study_test

這個(gè)目錄下,目前就只有一個(gè)文件,這個(gè)文件是用來記錄創(chuàng)建數(shù)據(jù)庫時(shí)配置的字符集的內(nèi)容。

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

現(xiàn)在新建兩個(gè)表,第一個(gè)表的引擎類型選擇InnoDB,第二個(gè)表的引擎類型選擇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引擎類型表';

將兩個(gè)表創(chuàng)建完成后,我們?cè)龠M(jìn)入到/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

通過目錄中的文件可看到創(chuàng)建表之后多了幾個(gè)文件,這樣也看出來了,InnoDB引擎類型的表和MyISAM引擎類型的表的文件差異。

這幾個(gè)文件每個(gè)都是有自己的作用:

  • InnoDB引擎的表文件,一共有兩個(gè):

    • *.frm 這類文件是表的定義文件。

    • *.ibd 這類文件是數(shù)據(jù)和索引存儲(chǔ)文件。表數(shù)據(jù)和索引聚集存儲(chǔ),通過索引能直接查詢到數(shù)據(jù)。

  • MyIASM引擎的表文件,一共有三個(gè):

    • *.frm 這類文件是表的定義文件。

    • *.MYD 這類文件是表數(shù)據(jù)文件,表中的所有數(shù)據(jù)都保存在此文件中。

    • *.MYI 這類文件是表的索引文件,MyISAM存儲(chǔ)引擎的索引數(shù)據(jù)單獨(dú)存儲(chǔ)。

MyISAM數(shù)據(jù)存儲(chǔ)引擎,索引與數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu)

MyISAM存儲(chǔ)引擎在存儲(chǔ)索引的時(shí)候,是將索引數(shù)據(jù)單獨(dú)存儲(chǔ),并且索引的B+Tree最終指向的是數(shù)據(jù)存在的物理地址,而不是具體的數(shù)據(jù)。然后再根據(jù)物理地址去數(shù)據(jù)文件(*.MYD)中找到具體的數(shù)據(jù)。

如下圖所示:
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
那么當(dāng)存在多個(gè)索引時(shí),多個(gè)索引都指向相同的物理地址。
如下圖所示:
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
通過這個(gè)結(jié)構(gòu),我們可以看出來,MyISAM的存儲(chǔ)引擎的索引都是同級(jí)別的,主鍵和非主鍵索引結(jié)構(gòu)和查詢方式完全一樣。

InnoDB數(shù)據(jù)存儲(chǔ)引擎,索引與數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu)

首先InnoDB的索引分為聚簇索引和非聚簇索引,聚簇索引即保存關(guān)鍵字又保存數(shù)據(jù),在B+Tree的每個(gè)分支節(jié)點(diǎn)上保存關(guān)鍵字,葉子節(jié)點(diǎn)上保存數(shù)據(jù)。
聚簇”的意思是數(shù)據(jù)行被按照一定順序一個(gè)個(gè)緊密地排列在一起存儲(chǔ)。一個(gè)表只能有一個(gè)聚簇索引,因?yàn)樵谝粋€(gè)表中數(shù)據(jù)的存放方式只有一種,一般是主鍵作為聚簇索引,如果沒有主鍵,InnoDB會(huì)默認(rèn)生成一個(gè)隱藏的列作為主鍵。

如下圖所示:
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
非聚簇索引,又稱為二級(jí)索引,雖然也是在B+Tree的每個(gè)分支節(jié)點(diǎn)上保存關(guān)鍵字,但是葉子節(jié)點(diǎn)不是保存的數(shù)據(jù),而是保存的主鍵值。通過二級(jí)索引去查詢數(shù)據(jù)會(huì)先查詢到數(shù)據(jù)對(duì)應(yīng)的主鍵,然后再根據(jù)主鍵查詢到具體的數(shù)據(jù)行。

如下圖所示:
InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些
由于非聚簇索引的設(shè)計(jì)結(jié)構(gòu),導(dǎo)致了,非聚簇索引在查詢的時(shí)候要進(jìn)行兩次索引檢索,這樣設(shè)計(jì)的好處,可以保證了一旦發(fā)生數(shù)據(jù)遷移的時(shí)候,只需要更新主鍵索引即可,非聚簇索引并不用動(dòng),而且也規(guī)避了像MyISAM的索引那樣存儲(chǔ)物理地址,在數(shù)據(jù)遷移的時(shí)候的需要重新維護(hù)所有索引的問題。

總結(jié)

這次把MySQL的索引的數(shù)據(jù)結(jié)構(gòu),以及文件存儲(chǔ)結(jié)構(gòu),總結(jié)清楚了,后面在實(shí)際的工作過程中,設(shè)計(jì)索引的時(shí)候能夠考慮的更全了,通過了解了索引的數(shù)據(jù)結(jié)構(gòu),也能讓自己在實(shí)際寫SQL的時(shí)候,能考慮到哪些情況走索引哪些不走索引了。

  • MySQL使用B+Tree作為索引的數(shù)據(jù)結(jié)構(gòu),因?yàn)锽+Tree的深度低,節(jié)點(diǎn)保存的關(guān)鍵字多,磁盤IO次數(shù)少,從而保證了查詢效率更高。

  • B+Tree能夠保證MySQL無論是主鍵索引還是非主鍵索引的查詢效果都是穩(wěn)定的,每次都要查詢到葉子節(jié)點(diǎn)才能返回?cái)?shù)據(jù),B+Tree的葉子節(jié)點(diǎn)的深度是一樣的,而且為了更好的支持自增主鍵,B+Tree的查詢節(jié)點(diǎn)范圍是左閉合右開放。

  • MySQL的MyISAM存儲(chǔ)引擎,表數(shù)據(jù)索引數(shù)據(jù)是分別放到兩個(gè)文件中進(jìn)行存儲(chǔ)的,由于它本身的索引的B+Tree的葉子節(jié)點(diǎn)指向的表數(shù)據(jù)所在的磁盤地址,而且索引沒有主鍵和非主鍵之分,所以分開存儲(chǔ),能夠更好的統(tǒng)一管理索引;

  • MySQL的InnoDB存儲(chǔ)引擎,表數(shù)據(jù)索引數(shù)據(jù)是存儲(chǔ)在一個(gè)文件中的,因?yàn)镮nnoDB的聚簇索引的葉子節(jié)點(diǎn)指向的具體的數(shù)據(jù)行,而且為了保證查詢效果的穩(wěn)定,InnoDB表中必須要有一個(gè)聚簇索引,二級(jí)索引在進(jìn)行索引檢索時(shí),會(huì)先通過二級(jí)索引檢索到數(shù)據(jù)的主鍵值,再根據(jù)主鍵去聚簇索引中檢索到具體的數(shù)據(jù)。

關(guān)于“InnoDB的數(shù)據(jù)存儲(chǔ)文件和MyISAM的不同有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI