1. 程式人生 > >MySQL 聚簇索引&&二級索引&&輔助索引

MySQL 聚簇索引&&二級索引&&輔助索引

MySQL非聚簇索引&&二級索引&&輔助索引

mysql中每個表都有一個聚簇索引(clustered index ),除此之外的表上的每個非聚簇索引都是二級索引,又叫輔助索引(secondary indexes)。

以InnoDB來說,每個InnoDB表具有一個特殊的索引稱為聚集索引。如果您的表上定義有主鍵,該主鍵索引是聚集索引。如果你不定義為您的表的主鍵時,MySQL取第一個唯一索引(unique)而且只含非空列(NOT NULL)作為主鍵,InnoDB使用它作為聚集索引。如果沒有這樣的列,InnoDB就自己產生一個這樣的ID值,它有六個位元組,而且是隱藏的,使其作為聚簇索引。

聚簇索引和聚集索引(Clustered Index)

說起索引,不能不說B+樹。

MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。提取句子主幹,就可以得到索引的本質:索引是資料結構。

我們知道,資料庫查詢是資料庫的最主要功能之一。我們都希望查詢資料的速度能儘可能的快,因此資料庫系統的設計者會從查詢演算法的角度進行優化。最基本的查詢演算法當然是順序查詢(linear search),這種複雜度為O(n)的演算法在資料量很大時顯然是糟糕的,好在電腦科學的發展提供了很多更優秀的查詢演算法,例如二分查詢(binary search),二叉樹查詢(binary tree search)

等。如果稍微分析一下會發現,每種查詢演算法都只能應用於特定的資料結構之上,例如二分查詢要求被檢索資料有序,而二叉樹查詢只能應用於二叉查詢樹上,但是資料本身的組織結構不可能完全滿足各種資料結構(例如,理論上不可能同時將兩列都按順序進行組織),所以,在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用(指向)資料,這樣就可以在這些資料結構上實現高階查詢演算法。這種資料結構,就是索引。

MySQL就普遍使用B+Tree實現其索引結構。

聚簇索引並不是一種單獨的索引型別,而是一種資料儲存方式。具體的細節依賴於其實現方式,但InnoDB的聚簇索引實際上在同一個結構中儲存了B-Tree索引和資料行。

當表有聚簇索引時,他的資料行實際上存放在索引的葉子頁(leaf page)中。術語 “聚簇”表示資料行和相鄰的鍵值緊湊地儲存在一起(這並非總成立)。

因為無法同時把資料行存放在兩個不同的地方,索引一個表只能有一個聚簇索引。

注:葉子頁面包含完整的元組,而內節點頁面僅包含索引的列(索引的列為整型)。一些DBMS允許使用者指定聚簇索引,但是MySQL的儲存引擎到目前為止都不支援。InnoDB對主鍵建立聚簇索引。如果你不指定主鍵,InnoDB會用一個具有唯一且非空值的索引來代替。如果不存在這樣的索引,InnoDB會定義一個隱藏的主鍵,然後對其建立聚簇索引。一般來說,DBMS都會以聚簇索引的形式來儲存實際的資料,它是其它二級索引的基礎。

索引組織表(Index Organized Table, IOT) 

其實和聚簇索引說的是一個意思。

索引組織表(Index organized table, IOT)就是儲存在一個索引結構中的表。與堆組織表無序儲存不同的是,IOT中的資料按主鍵儲存和排序。

相比堆組織表,索引組織表能夠節省一部分空間,因為使用堆組織表時,我們必須為表和表的主鍵上的索引分別留出空間。而IOT則可以省去主鍵索引的開銷,因為資料就是按順序儲存的,可以當做索引使。換句話說,如果你只會通過一個表的主鍵來訪問這個表,這個表就適合建立成索引組織表。

舉例:

 1.一個客戶有很多地址資訊,客戶是一個表,客戶地址資訊是另外一個表。讀取一個客戶地址資訊的時候,如果這個客戶的所有地址資訊都存放在相鄰的地方,讀取速度就會快一些。這個時候,客戶地址資訊表適合建立成IOT。

2. 經常檢視一支股票的最近幾天的資訊,股票資訊一般是千萬級別的資料,如果能夠把最近幾天的資訊存放在一起就會快很多。

=========END=========

如下除主鍵外都是二級索引,或叫做輔助索引。

<code class="hljs markdown"><span class="hljs-quote">> show create table article

<span class="hljs-strong">*****<span class="hljs-strong">*****<span class="hljs-strong">*****<span class="hljs-strong">***** 1. row <span class="hljs-strong">*****<span class="hljs-strong">*****<span class="hljs-strong">*****<span class="hljs-strong">******

Table: article

Create TableCREATE TABLE <span class="hljs-code">`article` (

<span class="hljs-code">`id` int(11) NOT NULL AUTO_INCREMENT,

<span class="hljs-code">`title` varchar(255) NOT NULL,

<span class="hljs-code">`shortName` varchar(255) NOT NULL,

<span class="hljs-code">`authorId` int(11) NOT NULL,

<span class="hljs-code">`createTime` datetime NOT NULL,

<span class="hljs-code">`state` int(11) NOT NULL,

<span class="hljs-code">`totalView` int(11) DEFAULT NULL,

PRIMARY KEY (<span class="hljs-code">`id`),

UNIQUE KEY <span class="hljs-code">`idx_short_name_title` (<span class="hljs-code">`title`,<span class="hljs-code">`shortName`),

KEY <span class="hljs-code">`idx_author_id` (<span class="hljs-code">`authorId`)

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1

rows in set</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>