什麼是索引?索引又是用來幹什麼的?
一句話概括就是:索引就是為了調高資料的查詢效率
就像書的目錄一樣,如果你想找到某個知識點,通常我們都是翻看書的目錄。同樣,索引其實就是資料庫表的「目錄」。
索引的常見模型
實現索引的資料結構有很多,最常見的也是比較簡單的資料結構有雜湊表,有序陣列和搜尋樹。
雜湊表雜湊表是一種以鍵-值(key-value)形式儲存資料的結構,我們只需要輸入查詢的鍵key,就可以得到對應的值value。雜湊的思路是,把值放在陣列裡,用乙個雜湊函式把key換成乙個確定的位置,然後把value放在陣列的這個位置。
但是會有一種情況,就是多個不同的key有可能通過雜湊函式的換算得到相同的位置,解決這種情況就是在這個位置拉出乙個鍊錶。
假如我們有一張使用者表,使用者暱稱(nickname)字段使用的是雜湊索引,我們需要根據暱稱查詢使用者資訊,這時雜湊索引的示意圖如下所示:
示意圖中,user3和user4根據nickname欄位算出來的位置都是4,所以在4位置用了乙個鍊錶表示,當我們在查詢的時候,比如我們根據nickname4查詢,查詢步驟就是:先使用雜湊函式計算nickname3得到4,然後遍歷鍊錶直到找到user4。
優點:因為雜湊索引是根據索引字段計算位置,所以它的插入和根據key的查詢會很快。
缺點:因為雜湊索引是計算位置,而這個位置不一定是遞增的,所以使用雜湊索引做範圍查詢速度會很慢。如果要根據範圍查詢資料,就必須全部掃瞄一遍索引才能找到。
適合場景:雜湊表適用於等值查詢的場景,比如redis或者其他的nosql資料庫。
有序陣列
還是上面的例子,如果是使用有序陣列索引的話,示意圖如下:
這個陣列是根據nickname遞增順序儲存的,如果我們要查nickname2對應的使用者資訊,用二分查詢就可以很快找到對應的結果,時間複雜度為o(log(n))。
當然這個資料結構也是支援範圍查詢的,如果我們想要查到[nicknamex,nicknamey]這個區間的使用者資訊,我們只需要根據二分查詢找到第乙個nicknamex,然後向右遍歷陣列,找到找到最後乙個nicknamey的使用者即可。
優點:有序陣列因為存入的資料已經是排好序的,所以根據等值查到和範圍查到都比較快。
缺點:如果我們需要往陣列中間插入乙個值或者刪除中間的某個值,那就需要挪動這個值所在位置後面的所有元素,成本比較高。
適合場景:有序陣列適用於靜態儲存引擎,儲存不會再修改的資料,比如某個城市過去的人口數。
二叉搜尋樹
還是上面的例子,如果是二叉搜尋樹的話,示意圖如下:
二叉樹特點:每個節點的左兒子小於父節點,父節點小於右兒子。如果我們要查user2的話,跟著上圖我們的查詢路徑就是:usera -> userb -> userd -> user2。時間複雜度為o(log(n))。
優點:查詢效率高
缺點:因為索引不止存在於記憶體中,也要寫到磁碟裡。如果乙個二叉樹高度為20,我們查詢某個使用者資訊就要訪問20次磁碟,這個效率是非常低的。
適用場景:二叉樹適用於表資料比較少的引擎。
為了減少樹的高度,也就是減少對磁碟的訪問,資料庫索引就不能用二叉樹。那麼既然有二叉數,那就有n叉樹,這裡的n取決於資料塊的大小。
在mysql中,索引是在儲存引擎層實現的,不同儲存引擎的索引使用的資料結構可能都不一樣。innodb的索引使用的資料結構為b+樹。
innodb的索引模型
在innodb中,表都是根據主鍵順序以索引的i形式存放的,這種儲存方式的表稱為索引組織表。每乙個索引在innddb中都對應一棵b+樹。
假如我們有下面一張表:
create
table t(
id int
primary
key,
k int
notnull
,index
(k))
engine
=innodb
;
表中 r1~r5 的 (id,k) 值分別為 (100,1)、(200,2)、(300,3)、(500,5) 和 (600,6),兩棵樹的示例示意圖如下:
從圖中可以看出,根據葉子節點的資料,索引型別分為主鍵索引和非主鍵索引。
主鍵索引和非主鍵索引的區別:
主鍵索引的葉子節點存的是整行資料,在innodb裡,主鍵索引也叫做聚簇索引;非主鍵索引的葉子節點存的內容是主鍵的值,在innodb裡,非主鍵索引也叫做二級索引。
如果根據主鍵查詢,則只需要查詢id索引樹即可;如果根據非主鍵索引查詢(查詢的資料不只有主鍵),則需要查詢k索引樹找到對應的主鍵,然後根據主鍵到id索引在查詢一次。這個過程叫回表。
結束!
mysql二級索引的優缺點 聚簇索引的優缺點
聚簇索引並不是一種單獨的索引型別,而是一種資料儲存方式.比較常用的就是 innodb 中的聚簇索引,它實際上是在同一結構中儲存了 b tree 索引和資料行.也就是說乙個表的資料實際存放在索引的葉子頁中.mysql innodb 中的聚簇索引不能指定,只能 mysql 自動生成.innodb 中一般...
Mysql索引介紹及常見索引的區別
mysql索引概念 說說mysql索引,看到乙個很少比如 索引就好比一本書的目錄,它會讓你更快的找到內容,顯然目錄 索引 並不是越多越好,假如這本書1000頁,有500也是目錄,它當然效率低,目錄是要佔紙張的,而索引是要佔磁碟空間的。mysql索引主要有兩種結構 b tree索引和hash索引.ha...
mysql欄位預設 常見MySql欄位的預設長度
下面為您介紹了一些常見的mysql欄位的預設長度,供您參考學習,如果您對mysql欄位方面感興趣的話,不妨一看,相信對您會有所幫助。整型 tinyint 1 位元組 smallint 2 個位元組 mediumint 3 個位元組 int 4 個位元組 integer 4 個位元組 bigint 8...