本位出處:http://www.cnblogs.com/wy123/p/7211742.html (保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他) MySQL中的InnoDB引擎表索引類型有一下幾種(以下所說的索引,沒有特 ...
本位出處:http://www.cnblogs.com/wy123/p/7211742.html
(保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他)
MySQL中的InnoDB引擎表索引類型有一下幾種(以下所說的索引,沒有特殊說明,均指InnoDB引擎表索引。)
0 = Secondary Index,二級索引,
1 = Clustered Index,聚集索引
2 = Unique Index,唯一索引
3 = Primary Index,主鍵索引
32 = Full-text Index,全文索引
64 = Spatial Index,空間索引
128 = A secondary index that includes a virtual generated column.二級計算列索引。
其中二級索引,聚集索引,唯一索引,主鍵索引,二級計算列索引,按照邏輯存儲結構來看,都是B+樹來存儲的
這一點與其他資料庫的B+樹索引邏輯存儲結構上看,並沒有太大的不同,以上幾種索引都是從邏輯角度來劃分的。
如果從物理存儲角度來看,MySQL中的這幾類索引可以劃分為聚集索引和二級索引(或者叫非聚集索引)
其中,主鍵索引和聚集索引,可以歸類為聚集索引,二級索引,唯一索引,二級計算列索引都數據非聚集索引。
MySQL中的聚集索引
MySQL聚集索引就是根據主鍵,把整張表的數據,在邏輯上組織成一棵B+樹,因此一個表只能由一個聚集索引。
非葉子節點存儲聚集索引key值,葉子節點存儲表中的數據本身,葉子節點與葉子節點之間採用雙向鏈表的方式連接在一起。
瞭解MySQL的聚集索引之前,先瞭解一下MySQL主鍵生成機制。
MySQL的InnoDB必須有一個主鍵,
如果在建表的時候指定了主鍵,那麼這個主鍵就是該表的主鍵(聽起來這麼彆扭,主要是跟未指定主鍵的情況下,自動生成的額主鍵作對比)
如果在建表的時候沒有指定主鍵,那麼存儲引擎會自動為表上建一個主鍵列
1)對於指定了主鍵的表,主鍵生成的索引就是“主鍵索引”,
2)對於未指定主鍵的表,如果有(一個或者多個)非空的唯一索引,(第一個)非空唯一約束做主鍵
3)對於未指定主鍵的表,且沒有唯一約束的表,預設生成一個主鍵,該主鍵上生成的索引就是“聚集索引”,
實際上,前者的“主鍵索引”和後者的“聚集索引”,物理存儲上都可以歸屬為聚集索引
1,顯式主鍵索引(聚集索引)
如下截圖,創建了test_index_type_1
在建表的時候指定了主鍵,則主鍵預設生成主鍵索引,索引類型是3(從物理存儲角度看,是聚集索引)
在表創建完成之後創建了索引,生成的是二級索引,索引類型是0(從物理存儲角度看,是非聚集索引)
2,非空唯一約束生成的主鍵索引(聚集索引)
如下截圖,創建了test_index_type_2,
在建表的時候沒有指定了主鍵,但是指定了一個唯一的非空約束,那麼這個欄位會當做主鍵用,生成的索引類型是3(從物理存儲角度看,是聚集索引)
3,系統預設主鍵生成的聚集索引(聚集索引)
如下截圖,創建了test_index_type_3表,
在建表的時候沒有指定了主鍵,也沒有指定唯一的非空約束,InnoDB引擎會自動生成一個6位元組的指針,生成的索引類型是聚集索引,類型是1(從物理存儲角度看,是聚集索引)
非聚集索引
非聚集索引,非聚集索引同樣是B+樹的結構來存儲數據的,
與聚集索引做大的差異在於非聚集索的葉子節點存儲的僅僅是索引的key值+聚集索引的key值,但是不包括所有的非索引鍵值。
1,唯一索引約束生成的唯一索引(非聚集索引)
如下截圖,創建了test_index_type_4表,
指定了id為unique的,那麼會自動在id列上創建一個唯一索引。
2,手動創建的唯一索引(非聚集索引)
如下截圖,創建了test_index_type5表,
手動在創建一個唯一的索引,那麼這個索引類型為唯一索引
3,手動創建的二級索引(非聚集索引)
如下截圖,創建了test_index_type6表,
那手動在創建一個的索引(未指定unique),那麼這個索引類型為二級索引
4,計算列索引,在計算列上手動創建索引(非聚集索引)
如下截圖,創建了test_index_type7表,
test_index_type7上有一個計算列,創建完成之後在計算列上加索引,索引為計算列索引
總結:
整體上來看,MySQL的幾種類型的B+樹的索引還是比較容易理解的,跟SQL Server中的索引也比較類似。
MySQL的InnoDB引擎表中,主鍵索引,非空唯一約束生成的聚集索引,聚集索引,從物理存儲上看都數據聚集索引。
主鍵索引,非空唯一約束生成的聚集索引,聚集索引,三者有一個明顯的特點,都要求所在的列是非空且唯一的。
另外就是MySQL無法顯式創建聚集索引,也即create clustered index.
這一點與SQL Server有很大的不同,
1,在SQL Server中,如果沒有指定主鍵,或者指定了主鍵沒有但是其nonclustered,那麼表就是為堆表,系統不會添加預設欄位作為聚集索引
2,SQL Server的主鍵可以僅僅是主鍵,可以不是聚集索引(預設情況下主鍵是聚集索引)。
聚集索引可以指定在任意一個列上,可以是非主鍵列,可以是非唯一,可為null,可重覆的列,比如如下