真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

mysql的索引怎么存儲(chǔ) mysql索引是如何存儲(chǔ)的

Mysql InnoDB索引原理

理解Mysql索引的原理和數(shù)據(jù)結(jié)構(gòu)有助于我們更好的使用索引以及進(jìn)行SQL優(yōu)化,索引是在存儲(chǔ)引擎層面實(shí)現(xiàn)的,所以不同的引擎實(shí)現(xiàn)的索引也有一定的區(qū)別,但是在生產(chǎn)環(huán)境中,我們最常用的就是InnoDB引擎和B樹(shù)索引,OK,那本文要討論的重點(diǎn)也同樣是 InnoDB引擎下的B樹(shù)索引 。

創(chuàng)新互聯(lián)的客戶來(lái)自各行各業(yè),為了共同目標(biāo),我們?cè)诠ぷ魃厦芮信浜希瑥膭?chuàng)業(yè)型小企業(yè)到企事業(yè)單位,感謝他們對(duì)我們的要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。專業(yè)領(lǐng)域包括網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、電商網(wǎng)站開(kāi)發(fā)、微信營(yíng)銷、系統(tǒng)平臺(tái)開(kāi)發(fā)。

我們建立一個(gè)表來(lái)進(jìn)行測(cè)試,表的DDL如下所示,我們要關(guān)注的是表t_book上的主鍵索引id和name author publish_date三列組成的索引test_index。

Mysql中的B樹(shù)索引是使用B+樹(shù)實(shí)現(xiàn)的,關(guān)于B+樹(shù)的數(shù)據(jù)結(jié)構(gòu)個(gè)人認(rèn)為美團(tuán)點(diǎn)評(píng)技術(shù)博客中Mysql索引原理及慢查詢優(yōu)化一文中介紹的非常詳實(shí),B+樹(shù)的數(shù)據(jù)結(jié)構(gòu)如下圖所示。

圖中淺藍(lán)色塊即磁盤塊,根節(jié)點(diǎn)磁盤塊中存儲(chǔ)17和35兩個(gè)數(shù)據(jù),其中指針P1指向小于17的數(shù)據(jù),指針P2指向大于17小于35的數(shù)據(jù),指針P3指向大于35的數(shù)據(jù)。顯然通過(guò)B+樹(shù)索引查詢數(shù)據(jù)與B+樹(shù)的高度有關(guān),如上圖的B+樹(shù)索引查找一個(gè)葉子節(jié)點(diǎn)的數(shù)據(jù)只需要三次磁盤IO,對(duì)于Mysql來(lái)說(shuō)三層的B+樹(shù)可以索引上百萬(wàn)的數(shù)據(jù),這對(duì)于查詢效率的提升是巨大的。

總結(jié)起來(lái)Mysql中B樹(shù)索引有以下關(guān)鍵特點(diǎn):

Mysql中的B樹(shù)索引有兩種數(shù)據(jù)存儲(chǔ)形式,一種為聚簇索引,一種為二級(jí)索引。

InnoDB一般會(huì)使用表的主鍵來(lái)作為聚簇索引,如果一個(gè)表沒(méi)有主鍵(不建議這么玩)InnoDB會(huì)選用一個(gè)唯一非空索引來(lái)代替,如果沒(méi)有這樣的索引,InnoDB會(huì)隱式建立一個(gè)聚簇索引。聚簇的含義即是數(shù)據(jù)行和相鄰的鍵值緊湊的存儲(chǔ)在一起,占據(jù)一塊連續(xù)的磁盤空間,因此通過(guò)聚簇索引訪問(wèn)數(shù)據(jù)可以有效減少隨機(jī)IO,通常使用聚簇索引查找比非聚簇索引查找速度更快。以我們建立的表t_book為例,聚簇索引即為自增主鍵id,其B樹(shù)索引數(shù)據(jù)結(jié)構(gòu)可以用下圖來(lái)表示。

聚簇索引有以下關(guān)鍵特點(diǎn):

InnoDB的B樹(shù)索引中除了聚簇索引,就都是二級(jí)索引了,二級(jí)索引的含義是索引的葉子節(jié)點(diǎn)除了存儲(chǔ)了索引值,還存儲(chǔ)了主鍵id,在使用二級(jí)索引進(jìn)行查詢時(shí),查找到二級(jí)索引B樹(shù)上的葉子節(jié)點(diǎn)后還需要去聚簇索引上去查詢真實(shí)數(shù)據(jù),但是這里有一種特殊情況,即查詢所需的所有字段在二級(jí)索引中都可以獲取,此時(shí)就不需要再去回表查數(shù)據(jù)了,這種情況就是索引覆蓋(EXPLAIN中EXTRA列中會(huì)出現(xiàn)USING INDEX,本文只關(guān)注索引結(jié)構(gòu),不詳細(xì)討論索引覆蓋等技術(shù)的使用,如果深入理解索引的數(shù)據(jù)結(jié)構(gòu),索引覆蓋等技術(shù)也沒(méi)有那么神秘)。

在我們的測(cè)試表t_book中,test_index即為二級(jí)索引,由于我們把除了主鍵id所有的列都作為一個(gè)聯(lián)合索引,所以在這個(gè)表上的查詢都可以使用索引覆蓋技術(shù),但是具體生產(chǎn)環(huán)境中也不建議總是采用這種做法,索引列的增加也會(huì)增大插入更新數(shù)據(jù)時(shí)的索引更新成本,具體的優(yōu)化要視具體情況決策。t_book上的二級(jí)索引test_index的索引結(jié)構(gòu)由下圖表示。

通過(guò)以上結(jié)構(gòu),我們可以推斷出二級(jí)索引的以下關(guān)鍵特點(diǎn):

索引覆蓋:

最左前綴匹配:

二級(jí)索引可以說(shuō)是我們?cè)贛ysql中最常用的索引,通過(guò)理解二級(jí)索引的索引結(jié)構(gòu)可以更容易理解二級(jí)索引的特性和使用。

最后聊點(diǎn)輕松的索引結(jié)構(gòu),哈希索引就是通過(guò)哈希表實(shí)現(xiàn)的索引,即通過(guò)被索引的列計(jì)算出哈希值,并指向被索引的記錄。

哈希索引有如下特性:

Mysql索引原理及慢查詢優(yōu)化

高性能Mysql 第三版

Mysql分區(qū)表時(shí)候索引如何進(jìn)行存儲(chǔ)

正常MySQL底層存儲(chǔ)索引默認(rèn)使用的是B+樹(shù),但是如果設(shè)立了分區(qū)表的情況下,他的底層是如何進(jìn)行存儲(chǔ)的呢?

查看MySQL對(duì)應(yīng)的自己電腦上面的安裝目錄下,是有一個(gè)ibd文件,用innblock和bcview兩個(gè)小工具,(github上可以搜到),便可以實(shí)現(xiàn)對(duì)ibd文件的查看,通過(guò)對(duì)比著沒(méi)有設(shè)立分區(qū)的表的ibd文件,就可以看出來(lái)

分區(qū)表會(huì)將索引分成分區(qū)個(gè)個(gè)數(shù)的索引樹(shù)來(lái)存儲(chǔ)索引,也就是分開(kāi)存儲(chǔ)。

「Mysql索引原理(六)」聚簇索引

? ?本節(jié)課主要關(guān)注InnoDB,但是這里討論的原理對(duì)于任何支持聚簇索引的存儲(chǔ)引擎都是適用的。

? ?葉子節(jié)點(diǎn)包含了全部數(shù)據(jù),其他節(jié)點(diǎn)只包含索引列。InnoDB將通過(guò)主鍵聚集數(shù)據(jù),也就是說(shuō)上圖中的“被索引的列”就是主鍵列。如果沒(méi)有定義主鍵,InnoDB會(huì)選擇一個(gè)唯一的非空索引代替。如果沒(méi)有這樣的索引InnoDB會(huì)隱式定義一個(gè)主鍵來(lái)作為聚簇索引。

? ?如果主鍵比較大的話,那輔助索引將會(huì)變的更大,因?yàn)?輔助索引的葉子存儲(chǔ)的是主鍵值;過(guò)長(zhǎng)的主鍵值,會(huì)導(dǎo)致非葉子節(jié)點(diǎn)占用占用更多的物理空間

所以建議使用int的auto_increment作為主鍵

? ?主鍵的值是順序的,所以 InnoDB 把每一條記錄都存儲(chǔ)在上一條記錄的后面。當(dāng)達(dá)到頁(yè)的最大值時(shí),下一條記錄就會(huì)寫(xiě)入新的頁(yè)中。一旦數(shù)據(jù)按照這種順序的方式加載,主鍵頁(yè)就會(huì)近似于被順序的記錄填滿。

? ?聚簇索引的數(shù)據(jù)的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那么對(duì)應(yīng)的數(shù)據(jù)一定也是相鄰地存放在磁盤上的。如果主鍵不是自增id,那么可以想 象,它會(huì)干些什么,不斷地調(diào)整數(shù)據(jù)的物理地址、分頁(yè),當(dāng)然也有其他一些措施來(lái)減少這些操作,但卻無(wú)法徹底避免。但,如果是自增的,那就簡(jiǎn)單了,它只需要一 頁(yè)一頁(yè)地寫(xiě),索引結(jié)構(gòu)相對(duì)緊湊,磁盤碎片少,效率也高。

? ?因?yàn)镸yISAM的主索引并非聚簇索引,那么他的數(shù)據(jù)的物理地址必然是凌亂的,拿到這些物理地址,按照合適的算法進(jìn)行I/O讀取,于是開(kāi)始不停的尋道不停的旋轉(zhuǎn)。聚簇索引則只需一次I/O。(強(qiáng)烈的對(duì)比)

? ?不過(guò),如果涉及到大數(shù)據(jù)量的排序、全表掃描、count之類的操作的話,還是MyISAM占優(yōu)勢(shì)些,因?yàn)樗饕伎臻g小,這些操作是需要在內(nèi)存中完成的。

? ?MyISM使用的是非聚簇索引, 非聚簇索引的兩棵B+樹(shù)看上去沒(méi)什么不同 ,節(jié)點(diǎn)的結(jié)構(gòu)完全一致只是存儲(chǔ)的內(nèi)容不同而已,主鍵索引B+樹(shù)的節(jié)點(diǎn)存儲(chǔ)了主鍵,輔助鍵索引B+樹(shù)存儲(chǔ)了輔助鍵。表數(shù)據(jù)存儲(chǔ)在獨(dú)立的地方,這兩顆B+樹(shù)的葉子節(jié)點(diǎn)都使用一個(gè)地址指向真正的表數(shù)據(jù),對(duì)于表數(shù)據(jù)來(lái)說(shuō),這兩個(gè)鍵沒(méi)有任何差別。由于 索引樹(shù)是獨(dú)立的,通過(guò)輔助鍵檢索無(wú)需訪問(wèn)主鍵的索引樹(shù) 。

? ?所以說(shuō),聚簇索引性能最好而且具有唯一性,所以非常珍貴,必須慎重設(shè)置。 一般要根據(jù)這個(gè)表最常用的SQL查詢方式來(lái)進(jìn)行選擇,某個(gè)字段作為聚簇索引,或組合聚簇索引 ,這個(gè)要看實(shí)際情況。

? ?聚簇索引和非聚簇索引的數(shù)據(jù)分布有區(qū)別,主鍵索引和二級(jí)索引的數(shù)據(jù)分布也有區(qū)別,通常會(huì)讓人感到困擾和以外,下面通過(guò)一個(gè)列子來(lái)講解InnoDB和MyISAM是如何存儲(chǔ)數(shù)據(jù)的:

? ?該表的主鍵取值1~10000,按照隨機(jī)順序插入并使用optimize table命令做了優(yōu)化。換句話說(shuō),數(shù)據(jù)在磁盤上的存儲(chǔ)方式已是最優(yōu),但行的順序是隨機(jī)的。列col2的值是從1~100之間隨機(jī)賦值,所以有很多重復(fù)的值。

? ?MyISAM的數(shù)據(jù)分布很簡(jiǎn)單,所以先介紹它。MyISAM按照數(shù)據(jù)插入的順序存儲(chǔ)在磁盤上,如下圖所示:

在行的旁邊顯示行號(hào),從0開(kāi)始遞增。因?yàn)樾惺嵌ㄩL(zhǎng)的,所以MyISAM可以從表的開(kāi)頭跳過(guò)所需的字節(jié)找到需要的行。

col2上的索引

? ?事實(shí)上,MyISAM中主鍵索引和其他索引在結(jié)構(gòu)上沒(méi)有什么不同。主鍵索引就是一個(gè)名為PRIMARY的唯一非空索引。

? ?InnoDB支持聚簇索引,所以使用不同的方式存儲(chǔ)同樣的數(shù)據(jù)。

? ?第一眼看上去,感覺(jué)和前面的沒(méi)什么區(qū)別,但是該圖顯示了整個(gè)表,而不是只有索引。因?yàn)樵贗nnoDB中,聚簇索引就是表,所以不像MyISAM那樣需要獨(dú)立的行存儲(chǔ),這也是為什么MyISAM索引和數(shù)據(jù)結(jié)構(gòu)是分開(kāi)的。

? ?聚簇索引的每一個(gè)葉子節(jié)點(diǎn)都包含了主鍵值。事務(wù)ID、用于事務(wù)和MVCC的回滾指針以及所有的剩余列。如果主鍵是一個(gè)列前綴索引,InnoDB也會(huì)包含完整的主鍵列和剩下的其他列。

? ?還有一點(diǎn)和MyISAM不同的是,InnoDB的二級(jí)索引和聚簇索引很不相同。InnoDB的二級(jí)索引的葉子節(jié)點(diǎn)中存儲(chǔ)的不是“行指針”,而是主鍵值,并以此作為指向行的“指針”。這樣的策略減少了當(dāng)出現(xiàn)行移動(dòng)或者數(shù)據(jù)頁(yè)分裂時(shí)二級(jí)索引的維護(hù)工作。使用主鍵值當(dāng)作指針會(huì)讓二級(jí)索引占用更多的空間,換來(lái)的好處是,InnoDB在移動(dòng)時(shí)無(wú)需更新二級(jí)索引中的這個(gè)“指針”。

? ?我們?cè)趤?lái)看一下 col2索引 。

? ?每一個(gè)葉子節(jié)點(diǎn)包含了索引列(這里是col2),緊接著是主鍵值(col1),上圖我們省略了非葉子節(jié)點(diǎn)這樣的細(xì)節(jié)。InnoDB非葉子節(jié)點(diǎn)包含了索引列和一個(gè)指向下一級(jí)節(jié)點(diǎn)的指針。

? ?最后,以一張圖表示InnoDB和MyISAM保存數(shù)據(jù)和索引的區(qū)別。

? ?前面講過(guò),最好使用AUTO_INCREMENT自增列來(lái)聚集數(shù)據(jù),避免隨機(jī)的、不連續(xù)的、值分布范圍大的列做聚簇索引,特別是對(duì)于I/O密集型的應(yīng)用。例如,從性能角度考慮,使用UUID來(lái)作為聚簇索引則會(huì)很糟糕:他使得聚簇索引的插入變得完全隨機(jī),這是最壞的情況,使得數(shù)據(jù)沒(méi)有任何聚集特性。

? ?為了演示這一點(diǎn),我們做兩個(gè)基準(zhǔn)測(cè)試:

1、使用證書(shū)ID插入userinfo表,和uuid作為主鍵的userinfo_uuid表

? ?userinfo_uuid表跟userinfo表除了主鍵給為UUID,其他字段都一樣

? ?測(cè)試這兩個(gè)表的設(shè)計(jì),首先在一個(gè)有足夠內(nèi)存容納索引的服務(wù)器上向這兩個(gè)表各插入100萬(wàn)條記錄。然后向兩個(gè)表繼續(xù)插入300萬(wàn)數(shù)據(jù),使索引的大小超過(guò)服務(wù)器的內(nèi)存容量。測(cè)試結(jié)果如下:

? ?向UUID主鍵插入行不僅花費(fèi)的時(shí)間更長(zhǎng),而且索引占用的空間也更大。這一方面是由于主鍵字段更長(zhǎng),另一方面毫無(wú)疑問(wèn)是由于頁(yè)分裂和碎片導(dǎo)致的。

? ?為了明白為什么會(huì)這樣,來(lái)看看往第一個(gè)表中插入數(shù)據(jù)時(shí),索引發(fā)生了什么變化。

自整型主鍵插入

? ?因?yàn)橹麈I是順序的,所以InnoDB把每一條記錄都存在上一條記錄的后面。當(dāng)達(dá)到頁(yè)的最大容量后,下一條記錄就會(huì)寫(xiě)入到新的頁(yè)中。一旦數(shù)據(jù)按照這種順序的方式加載,主鍵頁(yè)就會(huì)近似于被順序的記錄填滿,這也正是所期望的結(jié)果。

UUID插入

? ?因?yàn)樾滦械闹麈I值不一定比之前插入的大,所以InnoDB無(wú)法簡(jiǎn)單的總是把新行插入到索引的最后,而是需要為新的行尋找合適的位置,通常是已有數(shù)據(jù)的中間位置,并且分配空間。這會(huì)正價(jià)很多的額外工作,并導(dǎo)致數(shù)據(jù)分布不夠優(yōu)化。

缺點(diǎn):

把這些隨機(jī)值載入到聚簇索引后,也許需要做一次OPTIMIZE TABLE來(lái)重建表并優(yōu)化頁(yè)的填充。

結(jié)論 :使用InnoDB時(shí)應(yīng)盡可能地按主鍵順序插入數(shù)據(jù),并且盡可能地單調(diào)增加聚簇鍵的值來(lái)插入新行。

MySQL——關(guān)于索引的總結(jié)

首先說(shuō)說(shuō)索引的 優(yōu)點(diǎn) :最大的好處無(wú)疑就是提高查詢效率。有的索引還能保證數(shù)據(jù)的唯一性,比如唯一索引。

而它的 壞處 也很明顯:索引也是文件,我們?cè)趧?chuàng)建索引時(shí),也會(huì)創(chuàng)建額外的文件,所以會(huì)占用一些硬盤空間。其次,索引也需要維護(hù),我們?cè)谠黾觿h除數(shù)據(jù)的時(shí)候,索引也需要去變化維護(hù)。當(dāng)一個(gè)表的索引多了以后,資源消耗是很大的,所以必須結(jié)合實(shí)際業(yè)務(wù)再去確定給哪些列加索引。

再說(shuō)說(shuō)索引的基本結(jié)構(gòu)。一說(shuō)到這里肯定會(huì)脫口而出:B+樹(shù)!了解B+樹(shù)前先要了解二叉查找樹(shù)和二叉平衡樹(shù)。 二叉查找樹(shù) :左節(jié)點(diǎn)比父節(jié)點(diǎn)小,右節(jié)點(diǎn)比父節(jié)點(diǎn)大,所以二叉查找樹(shù)的中序遍歷就是樹(shù)的各個(gè)節(jié)點(diǎn)從小到大的排序。 二叉平衡樹(shù) :左右子樹(shù)高度差不能大于1。B+樹(shù)就是結(jié)合了它們的特點(diǎn),當(dāng)然,不一定是二叉樹(shù)。

為什么要有二叉查找樹(shù)的特點(diǎn)?? 因?yàn)椴檎倚士?,二分查找在這種結(jié)構(gòu)下,查找效率是很快的。 那為什么要有平衡樹(shù)的特點(diǎn)呢? 試想,如果不維護(hù)一顆樹(shù)的平衡性,當(dāng)插入一些數(shù)據(jù)后,樹(shù)的形態(tài)有可能變得很極端,比如左子樹(shù)一個(gè)數(shù)據(jù)沒(méi)有,而全在右子樹(shù)上,這種情況下,二分查找和遍歷有什么區(qū)別呢?而就是因?yàn)檫@些特點(diǎn)需要去維護(hù),所以就有了上面提到的缺點(diǎn),當(dāng)索引很多后,反而增加了系統(tǒng)的負(fù)擔(dān)。

接著說(shuō)B+樹(shù)。 它的結(jié)構(gòu)如下 :

可以發(fā)現(xiàn),葉子節(jié)點(diǎn)其實(shí)是一個(gè) 雙向循環(huán)鏈表 ,這種結(jié)構(gòu)的好處就是,在范圍查詢的時(shí)候,我只用找到一個(gè)數(shù)據(jù),就可以直接返回剩余的數(shù)據(jù)了。比如找小于30的,只用找到30,其余的直接通過(guò)葉子節(jié)點(diǎn)間的指針就可以找到。再說(shuō)說(shuō)其他特點(diǎn): 數(shù)據(jù)只存在于葉子節(jié)點(diǎn) 。當(dāng)葉子節(jié)點(diǎn)滿了,如果再添加數(shù)據(jù),就會(huì)拆分葉子節(jié)點(diǎn),父節(jié)點(diǎn)就多了個(gè)子節(jié)點(diǎn)。如果父節(jié)點(diǎn)的位置也滿了,就會(huì)擴(kuò)充高度,就是拆分父節(jié)點(diǎn),如25 50 75拆分成:25為左子樹(shù),75為右子樹(shù),50變成新的頭節(jié)點(diǎn),此時(shí)B+樹(shù)的高度變成了3。它們的擴(kuò)充的規(guī)律如下表,Leaf Page是葉子節(jié)點(diǎn),index Page是非葉子節(jié)點(diǎn)。

再說(shuō)說(shuō)B樹(shù) ,B樹(shù)相比較B+樹(shù),它所有節(jié)點(diǎn)都存放數(shù)據(jù),所以在查找數(shù)據(jù)時(shí),B樹(shù)有可能沒(méi)到達(dá)葉子節(jié)點(diǎn)就結(jié)束了。再者,B樹(shù)的葉子節(jié)點(diǎn)間不存在指針。

最后說(shuō)說(shuō)Hash索引 ,相較于B+樹(shù),Hash索引最大的優(yōu)點(diǎn)就是查找數(shù)據(jù)快。但是Hash索引最大的問(wèn)題就是不支持范圍查詢。試想,如果查詢小于30的數(shù)據(jù),hash函數(shù)是根據(jù)數(shù)據(jù)的值找到其對(duì)應(yīng)的位置,誰(shuí)又知道小于30的有哪幾個(gè)數(shù)據(jù)。而B(niǎo)+樹(shù)正好相反,范圍查詢是它的強(qiáng)項(xiàng)。

附錄: Hash到底是啥?? 哈希中文名散列,哈希只是它的音譯。 為啥都說(shuō)Hash快?? 首先有一塊哈希表(散列表),它的數(shù)據(jù)結(jié)構(gòu)是個(gè)數(shù)組,一個(gè)任意長(zhǎng)度的數(shù)據(jù)通過(guò)hash函數(shù)都可以變成一個(gè)固定長(zhǎng)度的數(shù)據(jù),叫hash值。然后通過(guò)hash值確定在數(shù)組中的位置,相同數(shù)據(jù)的hash值是相同的,所以我們存儲(chǔ)一個(gè)數(shù)據(jù)以后,只需O(1)的時(shí)間復(fù)雜度就可以找到數(shù)據(jù)。 那hash函數(shù)又是啥?? 算術(shù)運(yùn)算或位運(yùn)算,很多應(yīng)用里都有hash函數(shù),但實(shí)際運(yùn)算過(guò)程大不一樣。這是Java里String的hashCode方法:

publicint hashCode() {

}

還有一個(gè)問(wèn)題,hash函數(shù)計(jì)算出來(lái)的hash值有可能存在碰撞,即兩個(gè)不同的數(shù)據(jù)可能存在相同的hash值,在MySQL或其他的應(yīng)用中,如Java的HashMap等,如果存在碰撞就會(huì)以當(dāng)前數(shù)組位置為頭節(jié)點(diǎn),轉(zhuǎn)變成一個(gè)鏈表。

說(shuō)到這里也清楚了為啥Java中引用類型要同時(shí)重寫(xiě)hashCode和equals了。兩個(gè)對(duì)象,實(shí)例就算一模一樣,它們的hash值也不相等, 為啥不相等?? 默認(rèn)的Object的hashCode方法會(huì)根據(jù)對(duì)象來(lái)計(jì)算hash值的,實(shí)例相同,但它們還是兩個(gè)不同的對(duì)象啊,所以我們重寫(xiě)hashCode時(shí),最簡(jiǎn)單的方法就是調(diào)用Object的hashCode方法,然后傳入該引用類型的屬性,讓hashCode方法只根據(jù)這幾個(gè)屬性來(lái)計(jì)算,那么實(shí)例相同的話,它們的hash值也會(huì)相等。等hashCode比較完后,如果相等再比較實(shí)例內(nèi)容,也就是equals,確保不是hash碰撞。

索引的分類

如果我們指定了一個(gè)主鍵,那么這個(gè)主鍵就是主鍵索引。如果我們沒(méi)有指定,Mysql就會(huì)自動(dòng)找一個(gè)非空的唯一索引當(dāng)主鍵。如果沒(méi)有這種字段,Mysql就會(huì)創(chuàng)建一個(gè)大小為6字節(jié)的自增主鍵。如果有多個(gè)非空的唯一索引,那么就讓第一個(gè)定義為唯一索引的字段當(dāng)主鍵,注意,是第一個(gè)定義,而不是建表時(shí)出現(xiàn)在前面的。

對(duì)于輔助索引來(lái)說(shuō),它們的B+樹(shù)結(jié)構(gòu)稍微有點(diǎn)特殊,它們的葉子節(jié)點(diǎn)存儲(chǔ)的是主鍵,而不是整個(gè)數(shù)據(jù)。所以在大部分情況下,使用輔助索引查找數(shù)據(jù),需要二次查找。但并不是所有情況都需要二次查找。比如查找的數(shù)據(jù)正好就是當(dāng)前索引字段的值,那么直接返回就行。這里提一句,B+樹(shù)的key就是對(duì)應(yīng)索引字段的內(nèi)容。

而輔助索引又有一些分類:唯一索引:不能出現(xiàn)重復(fù)的值,也算一種約束。普通索引:可以重復(fù)、可以為空,一般就是查詢時(shí)用到。前綴索引:只適用于字符串類型數(shù)據(jù),對(duì)字符串前幾個(gè)字符創(chuàng)建索引。全文索引:作用是檢測(cè)大文本數(shù)據(jù)中某個(gè)關(guān)鍵字,這也是搜索引擎的一種技術(shù)。

注意,聚集索引、非聚集索引和前面幾個(gè)索引的分類并不是一個(gè)層面上的。上面的幾個(gè)分類是從索引的作用來(lái)分析的。聚集、非聚集索引是從索引文件上區(qū)分的。主鍵索引就屬于聚集索引,即索引和數(shù)據(jù)存放在一起,葉子節(jié)點(diǎn)存放的就是數(shù)據(jù)。數(shù)據(jù)表的.idb文件就是存放該表的索引和數(shù)據(jù)。

輔助索引屬于非聚集索引,說(shuō)到這也就明白了。索引和數(shù)據(jù)不存放在一起的就是非聚集索引。在MYISAM引擎中,數(shù)據(jù)表的.MYI文件包含了表的索引, 該表的 葉子節(jié)點(diǎn)存儲(chǔ)索引和索引對(duì)應(yīng)數(shù)據(jù)的指針,指向.MYD文件的數(shù)據(jù)。

索引的幾點(diǎn)使用經(jīng)驗(yàn)

經(jīng)常被查詢的字段;經(jīng)常作為條件查詢的字段;經(jīng)常用于外鍵連接或普通的連表查詢時(shí)進(jìn)行相等比較字段;不為null的字段;如果是多條件查詢,最好創(chuàng)建聯(lián)合索引,因?yàn)槁?lián)合索引只有一個(gè)索引文件。

經(jīng)常被更新的字段、不經(jīng)常被查詢的字段、存在相同功能的字段

MySQL索引

MySQL的Innodb存儲(chǔ)引擎的索引分為聚集索引和非聚集索引兩大類

特點(diǎn):B+樹(shù)葉子節(jié)點(diǎn)存儲(chǔ)行數(shù)據(jù)

一個(gè)表中,必須有一個(gè)聚集索引,只能有一個(gè)聚集索引,Innodb通常把一個(gè)表的主鍵索引作為聚集索引,如果沒(méi)有主鍵InnoDB會(huì)選擇一個(gè)唯一索引代替。如果沒(méi)有這樣的索引,InnoDB會(huì)隱式的定義一個(gè)主鍵來(lái)作為聚集索引,這個(gè)字段為6個(gè)字節(jié),類型為長(zhǎng)整形。

利用主鍵索引查找行數(shù)據(jù)是最快的,建議使用自增主鍵原因是利于索引樹(shù)的構(gòu)建(主鍵自增寫(xiě)入時(shí)新插入的數(shù)據(jù)不會(huì)影響到原有頁(yè),插入效率高;但是如果主鍵是無(wú)序的或者隨機(jī)的,那每次的插入可能會(huì)導(dǎo)致原有頁(yè)頻繁的分裂,影響插入效率)

特點(diǎn):B+樹(shù)葉子節(jié)點(diǎn)存儲(chǔ)主鍵ID

一個(gè)表中可以有多個(gè)非聚集索引,每個(gè)非聚集索引即是一棵B+樹(shù)

通過(guò)非聚集索引查找數(shù)據(jù)時(shí),需要先在非聚集索引上找到主鍵ID,再?gòu)木奂饕@取行數(shù)據(jù),這個(gè)過(guò)程就稱之為回表

B樹(shù)索引中的B樹(shù)實(shí)際上是B+樹(shù),至于為什么使用B+樹(shù)而不使用B樹(shù)或者紅黑樹(shù)的原因在另外的文章中有提及。

特點(diǎn):

特點(diǎn):類似JDK中的HashMap,但無(wú)法支持范圍查詢

特點(diǎn):使用的算法仍然是B樹(shù)索引,不同的就是索引列的值必須唯一

對(duì)于普通索引來(lái)說(shuō),查找到滿足條件的第一個(gè)記錄后,需要查找下一個(gè)記錄,直到碰到第一個(gè)不滿足條件的記錄。

對(duì)于唯一索引來(lái)說(shuō),由于索引定義了唯一性,查找到第一個(gè)滿足條件的記錄后,就會(huì)停止繼續(xù)檢索,提升索引性能

另外插入行時(shí)會(huì)構(gòu)建該唯一索引,假如索引值重復(fù)將插入失敗,適合業(yè)務(wù)上做唯一性檢驗(yàn)

通過(guò)建立倒排索引,可以極大的提升檢索效率,解決判斷字段是否包含的問(wèn)題,但是業(yè)務(wù)上一般都不采用這種索引,而是使用ES處理全文搜索需求

僅對(duì)某個(gè)特定字段建立的索引,如(biz_id)

對(duì)多個(gè)字段建立的索引,如(biz_id,type)


網(wǎng)頁(yè)名稱:mysql的索引怎么存儲(chǔ) mysql索引是如何存儲(chǔ)的
當(dāng)前URL:http://weahome.cn/article/hgdhih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部