先介紹比較常見簡單的數據索引:哈希表、有序數組、搜索樹算法
哈希表是一種以鍵值存儲數據的結構,只用輸入key就能找到value。數據庫
哈希表就是把key放在一個位置,把值通過計算均勻的分佈在數組裏,多個 key 值通過哈希函數的換算,會出現同一個值的狀況。處理這種狀況的一種方法是,拉出一個鏈表。數組
例如你須要在哈希值爲2的鏈表裏面新增一個值,直接在尾部添加就行了,但若是須要在裏面查詢某一個值,你得掃描裏面全部的值,由於鏈表不是有序的。數據結構
哈希表這種結構適用於只有等值查詢的場景,好比 Memcached 及其餘一些NoSQL 引擎。函數
有序數組按數組遞增的順序排序,若是僅僅看查詢效率,有序數組就是最好的數據結構了。可是,在須要更新數據的時候就麻煩了,你往中間插入一個記錄就必須得挪動後面全部的記錄,成本過高。性能
二叉搜索樹的特色是:每一個節點的左兒子小於父節點,父節點又小於右兒子。3d
二叉樹搜索效率最高,可是數據存儲不使用二叉樹,由於索引可能還要寫入磁盤中,由於是二叉,數據量大的狀況下樹高可能有幾十,至關於幾十個數據塊,而磁盤讀取一個數據塊須要花費10ms,相對來講查詢太慢了。blog
樹能夠有二叉也能夠有多叉,每一個節點下面有多個兒子,N叉樹用很低的樹高,存儲龐大的數據,減小對磁盤的訪問,被普遍用於數據庫中。排序
B+樹相似於多叉樹,不過能夠在最後的子節點用雙向鏈表連了起來,好比我只須要找到8-10這個區間,而後經過8日後面遍歷找到後面的9。索引
這樣它完美地支持了咱們提的三個需求:快速查找值,區間,順序逆序查找。
在插入新值的時候,須要日後挪動位置,可是剛剛數據已經滿了,只能開啓新的一頁,根據 B+ 樹的算法,這時候須要申請一個新的數據頁,而後挪動部分數據過去。這個過程稱爲頁分裂,會影響性能。
若是是以自增 id 做爲主鍵,因爲新插入的表中生成的 id 比索引中全部的值都大,因此它要麼合到已存在的節點(元素個數未滿)中,要麼放入新建的節點中(以下圖示)因此若是是以自增 id 做爲主鍵,就不存在頁分裂的問題了。
也會有頁合併的狀況,刪掉了兩個數據,數據分散在兩個不一樣的節點上,可能形成兩次 IO 讀,勢必會影響查找效率! 那何時會發生頁合併呢,咱們能夠定個閾值,好比對於 N 叉樹來講,當節點的個數小於 N/2 的時候就應該和附近的節點合併,不過須要注意的是合併後節點裏的元素大小可能會超過 N,形成頁分裂,須要再對父節點等進行調整以讓它知足 N 叉樹的條件。
假若有很長的身份證,仍是用ID做爲主鍵呢,答案確定是用ID,由於索引越長佔用空間越大。