Innodb表的物理存儲結構及特性

Innodb表不同存儲格式的物理結構和特性:


當innodb表使用冗餘(REDUNDANT)行存儲格式有如下特性:
  • 1.每個索引記錄包含一個6字節的頭部,用於將邏輯上連續的記錄鏈接到一起,同時也用於行級鎖。
  • 2.聚集索引記錄包含所有用戶定義的列,即包含表中所有字段。此外,還有6字節的事務ID域,和7字節的回滾指針域。
  • 3.如果表沒有定義主鍵,每條聚集索引記錄則會包含6字節的ROW ID域。
  • 4.每個普通索引( secondary index)包含主鍵定義的所有字段。
  • 5.每條記錄都包含指向該記錄中每個字段的指針,如果行中所有記錄的總長度小於127字節,則指針佔用1個字節,否則佔用兩個字節。這些指針陣列稱之爲記錄目錄。這些指針指向的區域就是數據部分。
  • 6.Innodb在內部使用定長格式存儲定長字符類型的字段,比如char類型,Innodb不會截斷varchar類型字段的尾部空格。
  • 7.指針區域爲每個null字段保留1~2個字節,除此以外,如果字段定義爲變長類型,在記錄的數據域不佔用任何字節,如果定義爲定長類型,每個null字段佔用固定長度的字節。爲null保留定長的空間,能夠使字段從null變成not null時,不會造成索引頁碎片。


當innodb表使用緊湊(COMPACT )行存儲格式有如下特性:
  • 緊湊型行存儲格式相比冗餘型行存儲格式能減低大約20%的存儲空間,代價就是某些操作會增加cpu消耗。 如果系統負載是典型的受限於cache命中率和磁盤I/O帶寬,那麼使用COMPACT很可能會更快;但如果系統負載是罕見的受限於cpu,則使用COMPACT可能會更慢。
  • 每個索引記錄包含5字節的定長頭部,這個可能在變長頭部前面,用於將邏輯上連續的記錄鏈接到一起,同時也用於行級鎖。
  • 記錄的可變長頭部包含一個位圖矢量,用於指示包含包含null的字段。如果一個索引中包含N個定義爲null的字段,則位圖矢量需要CEILING(N/8)字節。定義爲null的字段除了位圖矢量佔用空間外,其它地方不需要存儲空間。可變長頭部也包含可變長字段的長度信息,其長度爲1~2字節,具體視可變長字段的最大長度而定。
  •  如果索引中所有字段都是非null類型,並且都是定長的,則沒有可變長頭部。
  • 對於每個非null的可變長字段,在記錄頭部爲每個字段使用1~2個字節用於記錄字段長度信息,如果一個字段的一部分被存儲在外部的溢出頁上,或者最大長度超過255字節並且實際長度超過127字節則需要2個字節,否則只需要一個字節。對於一個外部存儲字段,這2字節用於標識內部存儲部分的長度信息和用於指向的外部存儲部分的20個字節的指針。
  • 記錄的頭部跟在非null字段數據內容後面。
  • 聚集索引記錄包含所有用戶定義的列,即包含表中所有字段。此外,還有6字節的事務ID域,和7字節的回滾指針域。
  • 如果表沒有定義主鍵,每條聚集索引記錄則會包含6字節的ROW ID域。
  • 每個普通索引( secondary index)包含主鍵定義的所有字段;如果主鍵中存在任何可變長的字段,即使普通索引中定義的字段都是定長字段,每個普通索引記錄在頭部也會包含可變長度部分,用於記錄這些字段的長度。
  • 在內部,Innodb使用定長格式存儲定長字符類型的字段,比如char類型,Innodb不會截斷varchar類型字段的尾部空格。
  • 在內部,Innodb試圖通過截斷字段尾部空格的方式將utf8 CHAR(N) 跟 utf8mb4 CHAR(N) 的字段存儲在N個字節中。如果往定義爲CHAR(N)的字段中存儲超過N字節的值,Innodb會截斷值尾部部分,以最小化值。 定義爲CHAR(N)的字段最大長度爲字段中最大字符佔用字節數×N,即相應字段在系統表INFORMATION_SCHEMA.COLUMNS的CHARACTER_OCTET_LENGTH列的值。innodb爲CHAR(N)類型字段最小保留N個字節,保留這部分空間在很多情況下可以避免字段進行在線更新時產生索引頁碎片。


總結:
  1.   Innodb表字段類型的存儲會影響數據庫的查詢和DML性能,一個數據頁中能存放更多的由數字類型和短的字符串類型字段組成的記錄,這樣的記錄查詢起來速度更快,只需要 InnoDB buffer pool中更小的cache,以及更少的io。
  2.   每個innodb表數據被分成數據頁存儲,這些組成表的數據頁由一種叫B-Tree index的數據結構排列組成。表中的數據和普通索引都是由這種數據結構組成。它是根據主鍵列組織起來的代表整個表的B-Tree index稱之爲聚集索引。
  3.   聚集索引節點包含特定記錄的所有字段值,普通索引節點包含主鍵列和索引列。
  4.   可變長字段是個列外,如varchar,blog類型字段,如果這些類型的字段值太長以至於填滿整個數據頁,則會被分開存儲在一個叫溢出頁的數據頁上。這樣的字段稱之爲離頁字段,這些字段被存儲在溢出頁單鏈表中,每個字段都有一個獨立由一個或多個溢出頁組成的單鏈表;其它情況下(指字段值不會填滿數據頁),字段的所有值或部分前綴被存儲在同一頁中,避免浪費存儲以及消除需要單獨讀取一個單獨的數據頁的情況。
  5.   相比較而言, 行存儲格式爲冗餘型(ROW_FORMAT=REDUNDANT), utf8 和 utf8mb4 ;行存儲格式爲動態型(ROW_FORMAT=DYNAMIC)以及壓縮性(COMPRESSED),CHAR類型的存儲方式與緊湊型( ROW_FORMAT=COMPACT)一樣。
  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章