這個小節我們來談一下關於資料庫中的索引吧!
基本上,索引是一種 B-tree 的資料結構,主要用於加速資料的查詢以及更新,並大幅減少資料庫的壓力。[註1]
一般來說,資料庫使用者只會直接看到存放資料的資料表,然而實際上在 DB 裡面會存放著這些資料以 index 去建立 B-tree 的結構,有多少個 index 就會建立多少的 B-tree ,而實際在進行 SQL 處理時也是用 B-tree 去處理,並把結果更新在我們一般看到的表以及其他 index 的 B-tree 上。
介紹完了索引後,應該不難發現索引的高效能是建立在損失記憶體的狀況下達成的,因此如果不分你我直接將所有欄位都設定 index 的話,那就失去了當初 index 的意義了,不僅失去了記憶體,在更新的同時也會因為需要更新其他的 B-tree 而損失效能。那麼,通常我們會在什麼情境或條件去設定索引呢?以下三點是我們通常會考量的因素:
索引的類型可以分為叢集索引( Clustered index )以及非叢集索引( NonClustered index )。最好理解的方式是如參考資料的第一篇文章中所提到,叢集索引就有如一本書的目錄,而非叢集索引則像是一本書的附錄。一本書只會有一個目錄,但可以有零到多個附錄。
最重要的是,資料庫中的資料實際上是用叢集索引的方式去排列的,因此叢集索引基本上等於資料存放位置,而非叢集索引存放的是指標,負責告訴你要查的資料在哪個位置。
當我們辛辛苦苦建立完索引後,自然會希望此舉能增加我們查詢的效能,然而在實際應用中,有些 SQL 的情境反而會用不到我們建立好的索引,包含以下這些語句:
在不同資料庫中,索引所採用的 B-tree 結構稍有不同,分為 B tree 跟 B+ tree 兩種。大家常用的Mysql 採用 B+ tree ,而 mongoDB 採用 B tree 。
B tree 結構中的每個節點都會儲存所有數據;而 B+ tree 結構只有葉節點儲存所有數據,非葉節點則只儲存 key 。
最後來稍微區分一下這三個會讓人稍微混淆的名詞吧。
主鍵:設立目的是保持數據唯一性,以避免在特殊狀況下寫了兩筆完全相同的資料進去。每張表都只有一個主鍵(可設為多欄位),此外通常主鍵也會是索引之一。
外鍵:是為了建立表與表間的連結,透過外鍵可以更容易知道表之間是如何串接的。
索引:主要作用是加速資料的查詢,不論是單獨這張表,還是表與表之間的聯合查詢。
[註1] 在此不詳細解釋 Binary-tree 的相關內容,有興趣者可自行去查找資料。