InnoDB 中文參考手冊 --- 11 表和索引結構 (轉)

amyz發表於2007-08-15
InnoDB 中文參考手冊 --- 11 表和索引結構 (轉)[@more@] words" content="My,InnoDB,4.1.0,Shuixin13, 4.1.0,中文,中文參考手冊,犬犬(心帆)"> CSS rel=STYLESHEET>

結構

MySQL 在目錄下的 .frm 中它的資料字典資訊。但是每個 InnoDB 型別表也同樣在 InnoDB 表空間內的內部的資料字典中存在它自己的進入點。當 MySQL 移除(drop) 一個表或一個資料庫時,它將同時刪除 .frm 檔案,以及在 InnoDB 的資料字典中相對應的進入點。這就是為什麼不能透過簡單的刪除 .frm 檔案為移除資料庫中的 InnoDB 型別表的原因,以及為什麼在 MySQL 版本 <= 3.23.43 的版本中,DROP DATABASE 不能用於 InnoDB 表的原因。

每一個 InnoDB 表都有一個被稱為聚簇索引的特殊索引用於儲存記錄行資訊。如果一個表定義一個 PRIMARY KEY ,那麼主鍵的索引就是聚簇索引。

如果表沒有定義一個 PRIMARY KEY ,MySQL 將選出第一個 NOT NULL 欄位的 UNIQUE 鍵做為主鍵,InnoDB 也將用這個鍵的索引做為聚簇索引。如果表中沒有這樣的鍵,InnoDB 將在內部產生一個聚簇索引,它是由按 InnoDB 分配給它們的 row id 順序排序的記錄行組成。這個 row id 是一個單調地增加並插入新行的 6-byte 欄位。因而由 row id 排序的記錄順序也就是插入時的物理順序。

透過聚簇索引訪問一個記錄行是非常快的,因為記錄行資料與引導我們查詢到它的索引在同一個頁面上。 在大多數的資料庫中記錄行資料與索引記錄通常並不是放在同一個頁面上的。如果一個表太大了,那麼聚簇索引體系通常比傳統的方式更能減少 I/O 。

在非-聚簇索引(non-clustered indexes)中的記錄 (我們通常稱它為輔助索引secondary indexes),在 InnoDB 中會為這行包含主鍵值。InnoDB 將使用這個主鍵值來在聚簇索引中查詢這行。注意如果主鍵太長,那麼輔助索引將會佔用更多的空間。

InnoDB 在比較不同長度的 CHARVARCHAR 時,較短字串的多餘長度將被空格(spaces)填充。

All indexes in InnoDB 中所有的索引是索引記錄存放在樹的葉頁面(leaf pages)上的 B-trees。一個索引頁面的大小預設為 16 kB。當新的記錄被插入時,InnoDB 將試圖為將來的插入與索引記錄保留頁面的 1 / 16 空餘。

如果索引記錄以一個連續的 (升序或降序) 被插入,那麼索引頁面的將會被使用約 15/16 。如果以一個隨機的順序插入,那麼頁面大約使用了 1/2 - 15/16 。如果一個索引頁面被撤銷(drop)地低於 1/2,那麼 InnoDB 將縮短索引樹並釋放頁面空間。

主鍵是一個唯一識別符號,新的記錄以主鍵的升序被插入,這在資料庫系統中是一個普遍的情形。因而在聚簇索引內插入的值不需要在上隨意讀取。

另一方面,輔助索引通常是非唯一的(non-unique),插入在輔助索引中是相當隨意的順序。如果在 InnoDB 中不使用一個特殊的機制這將會引起大量隨機的磁碟 I/O。

如果一個索引記錄被插入到一個非唯一的輔助索引中去,InnoDB 將檢查輔助索引頁面是否已在緩衝池(buffer pool)中。在這種情形下,InnoDB 直接地將它插入到索引頁面中去。但是,如果在緩衝池中沒有發現索引頁面,InnDB 將索引記錄插入到一個特殊的插入緩衝結構中去。插入緩衝被控制地如些小以至於可以完全放在緩衝池中, 因而插入速度很快。

插入緩衝會定時地歸併到資料庫中的輔助索引樹中去。為了減少磁碟 I/O,通常將同一個頁面上的幾個插入同時歸併到索引樹上。插入緩衝可以提高向一個表中插入速度 15倍。

)

如果一個資料庫幾乎佔滿了所有主同存,那麼在其上執行查詢的一個快捷之路就是使用雜湊索引(hash indexes)。InnoDB 有一個用於監視在表定義的索引上的索引搜尋動作的自動調整結構,如果 InnoDB 發現一個雜湊索引對查詢有益,那麼它將自動地建造這個雜湊索引。

但是要注意地就是雜湊索引通常是基於表中已存在的 B-tree 建立的。InnoDB 可能透過 B-tree 中定義的任何長度的鍵的字首來構建雜湊索引,這依賴於 InnoDB 觀察 B-tree 上索引的。一個雜湊索引可以是部分的:它在緩衝池中並不需要有整個 B-tree 索引的高速緩衝。InnoDB 按照需要來為經常訪問的索引頁面構建雜湊索引。

在理論上,透過這個適應性的雜湊索引機制,InnpDB 使它自己更適合於大的主存(ample main memory),更接近於主儲存器資料庫系統體系(the architecture of main memory databases)。

  • InnoDB 中每個索引記錄都包含一個 6 位元組的頭。這個頭部用於聯連相連貫的記錄,也同樣用於行鎖定。
  • 聚簇索引中的記錄包含了所有定義的欄位。另外,有一個 6-byte 欄位用於記錄事務 id(transaction id)和一個 7-byte 欄位用於行指標(roll pointer)。
  • 在一個表中,如果使用者沒有定義一個主鍵,那麼每個聚簇索引記錄包含一個 6-byte 的行 id 欄位(row id field)。
  • 每個輔助索引記錄包含為聚簇索引鍵定義的所有欄位。
  • 一個索引包含著一個指向對應欄位記錄的指標。如果一個記錄的所有欄位總長度< 128 bytes,那麼這個指標為 1 byte,否則為 2 bytes。
  • InnoDB 在內部也是以一個固定長度來儲存定長的字元型欄位,比如 CHAR(10)。對於 VARCHAR 型欄位,InnoDB 將截去結尾的空間。注意,MySQL 可能內部地將 CHAR 轉換為 VARCHAR。檢視 MySQL 使用者手冊有關“列規約的預設地改變”( 'Silent column specification changes')。
  • 如果儲存一個變長的欄位,一個 SQL NULL 為一個 0 bytes 被儲存,但是如果是一個定長欄位將以固定的長度被儲存。以相應的 NULLs 儲存定長的空間的目的地就在於在將 NULL 欄位值更新為 非 NULL 的值時不至產生索引頁面的磁碟碎片。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-957804/,如需轉載,請註明出處,否則將追究法律責任。

相關文章