前言
在這里需要明確的一點是,數(shù)據(jù)庫的引擎InnoDB或者是MyISAM引擎它們是形容數(shù)據(jù)表的,不是形容數(shù)據(jù)庫的。
另外:文章中提到的索引的數(shù)據(jù)結(jié)構(gòu)暫且都默認使用B+Tree
InnoDB引擎
InnoDB的索引數(shù)據(jù)文件有兩個,tableName.frm和tableName.ibd文件。
- frm文件:表結(jié)構(gòu)相關(guān)信息
- ibd文件:所有數(shù)據(jù)(按照索引數(shù)據(jù)結(jié)構(gòu)構(gòu)建的)
在InnoDB表中,索引存儲的是葉子節(jié)點上存儲的是具體的數(shù)據(jù)。
MyISAM引擎
MyISAM的索引數(shù)據(jù)文件有三個,tableName.frm、tableName.MYD和tableName.MYI文件
- frm文件:表結(jié)構(gòu)的相關(guān)信息(字段啊什么信息)
- MYD文件:數(shù)據(jù)存儲(具體的數(shù)據(jù))
- MYI文件:索引存儲(存放索引數(shù)據(jù))
select * from table where table.Col1 = 30;
我們查詢上述Col1為30的數(shù)據(jù),會從MYI文件中索引數(shù)據(jù)結(jié)構(gòu)中查找對于的數(shù)據(jù),找到葉子節(jié)點之后MyISAM引擎的葉子節(jié)點不會存儲具體的數(shù)據(jù),而是存儲對于數(shù)據(jù)所在的磁盤地址,然后在從MYD文件中找到具體的對應(yīng)行數(shù)據(jù)。
在這里我們只了解兩種引擎下的數(shù)據(jù)存儲文件結(jié)構(gòu),了解了這兩種索引文件存儲結(jié)構(gòu)之后我們繼續(xù)往下
聚集索引(聚簇索引)
葉子節(jié)點包含了完整的數(shù)據(jù)記錄,在InnoDB的主鍵索引就是一個聚集索引。
非聚集索引(非聚簇索引)
比如MyISAM引擎的主鍵索引就是一個非聚集索引,MYI索引文件中的葉子節(jié)點存儲的數(shù)據(jù)對應(yīng)著MYD文件中的具體數(shù)據(jù)。
這里有三個問題:
1.為什么建議InnoDB表建議建主鍵,并且推薦使用整型的自增主鍵?
- 表數(shù)據(jù)文件(ibd)文件本身就是按照B+Tree組織的一個索引結(jié)構(gòu)文件,如果我們不建主鍵,它會默認選擇一列(所有數(shù)據(jù)不相等的數(shù)據(jù)),如果所有列都不符合的話它會幫我們建一個隱藏列,隱藏列會幫我們維護一個唯一ID,然后來組織整張表的索引數(shù)據(jù),這樣會造成不必要的開銷。
- 使用整型的主鍵是因為在進行索引查找的時候是從根節(jié)點進行查詢?nèi)缓筮M行大小比較整型的效率一定會大于非整形的比對效率,并且整型的磁盤空間占用要小于非整型
- 使用自增主鍵會增加插入效率,如果使用非自增的主鍵,會導(dǎo)致索引的數(shù)據(jù)結(jié)構(gòu)重新排列(B+Tree是排好序的數(shù)據(jù)結(jié)構(gòu))和樹的平衡,自增主鍵只會往右開辟節(jié)點
2.聚集索引和非聚集索引查詢效率如何?
從上面很容易看出來,聚集索引可以很直接的拿到數(shù)據(jù),因此聚集索引效率要高
3.為什么非主鍵索引(二級索引,非聚集索引)結(jié)構(gòu)葉子節(jié)點存儲的是主鍵值(如圖)
一致性和節(jié)省存儲空間:節(jié)約空間應(yīng)該比較好理解,一致性問題就是減少復(fù)雜增度,插入的時候只需要關(guān)注主鍵索引的數(shù)據(jù)就行。
聯(lián)合索引
如上圖,我們建立 name、age、position 的主鍵聯(lián)合索引。
聯(lián)合索引的數(shù)據(jù)結(jié)構(gòu)是有順序的,比如它先比較name的值,name的值相同在比較age,age相同在比較postion,可以仔細觀察一下上述的圖體會一下,然后在索引命中的時候是遵循最左前綴匹配的比如:
select * from table where name ='Bill'; select * from table where age = 30 and position='dev'; select * from table where position = 'dev';
比如上述Sql,只有第一個會命中索引,在或者如下sql文章來源:http://www.zghlxwxcb.cn/news/detail-521131.html
select * from table where age = 30 and position='dev' and name = 'Bill';
這個sql是可以進行索引查詢的,因為這種條件的情況下Mysql內(nèi)部會進行優(yōu)化。文章來源地址http://www.zghlxwxcb.cn/news/detail-521131.html
到了這里,關(guān)于【Mysql】索引數(shù)據(jù)結(jié)構(gòu)深入研究(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!