1. 程式人生 > >InnoDB存儲引擎表的邏輯存儲結構

InnoDB存儲引擎表的邏輯存儲結構

無法創建 方式 trail 單位 失去 不同的 text span 前綴

1.索引組織表: 在InnoDB存儲引擎中,表都是依照主鍵順序組織存放的。這樣的存儲方式的表稱為索引組織表,在innodb存儲引擎表中,每張表都有主鍵。假設創建的時候沒有顯式定義主鍵,則InnoDB會依照例如以下方式選擇或者創建主鍵: 1). 首先推斷表中是否有非空的唯一索引,假設有。則該列就為主鍵。 2). 假設不符合上述條件,則innodb會自己主動創建一個6字節大小的指針 假設表中有多個非空唯一索引時,InnoDB將選擇建表時第一個定義的非空唯一索引為主鍵,通過_rowid能夠顯示表的主鍵,可是僅僅能查看單個列作為主鍵的情況,對於多列組成的主鍵則不能夠。

2.InnoDB邏輯存儲結構 全部數據都會被邏輯的存放在一個空間中。稱為表空間,表空間由段(segment)、區(extent)、頁(page)組成。頁有時候也成為塊(block)。 表空間: 全部數據都存放在表空間。默認情況下有個共享表空間ibdata1,假設啟用了參數innodb_file_per_table。則每張表的數據能夠單獨放到一個表空間中(默覺得96kb)。可是僅僅存放一定的數據(數據、索引和插入緩沖bitmap頁),其它的數據還是存放在共享表空間中,因此在啟用這個參數後。共享表空間的大小還是會不斷增大。並且innodb存儲引擎不會在事務運行rollback時去收縮這個表空間,會推斷這些信息是否還須要,不須要則標為可用空間供下次使用。

段(segment):表空間由各個段組成,常見的段有數據段(B+樹的葉子節點)、索引段(B+樹的非葉子節點)、回滾段等。 存儲引擎中對段的管理是自身完畢的。

區(extent): 區是由連續頁組成的空間,不論什麽情況下每一個區的大小都為1MB。為了保證區中頁的連續性,innodb一次從磁盤申請4-5個區,默認情況下innodb頁的大小為16kb,即一個區有一共同擁有64個連續的頁。從innodb1.0.x版本號開始引入壓縮頁,即每一個頁的大小能夠通過參數KEY_BLOCK_SIZE設置為2K、4k、8k。

innodb1.2.x版本號開始新增參數innodb_page_size能夠將默認頁的大小設置為4k、8k,可是頁中的數據庫不是壓縮。 當中包括一個問題就是用戶啟用了innodb_file_per_table參數後。創建的表默認大小是96kb,可是區中是64個連續的頁,創建的表的大小應該至少是1MB才對,由於在每一個段開始時。先用32個頁大小的碎片頁來存放數據,使用完之後才申請64個連續頁,為了節省磁盤容量的開銷。 頁(page): 頁是innodb磁盤管理的最小單位。默認每一個頁的大小為16KB。常見的頁有:數據頁、undo頁、系統頁、事務數據頁、插入緩沖位圖頁等。
:每一個頁存放的行記錄最多同意存放16kb/2-200行記錄, 3.innodb行記錄格式: innodb存儲引擎中的記錄是以行的形式存儲的。這意味著頁中保存著一行行的數據,在innodb1.0.x之前,提供了compact和redundant兩種格式存放行記錄數據, 3.1. compact行記錄格式: mysql5.0以後引入,為了高效的存儲數據,一個頁中存放的行數據越多,性能越高,其存儲方式為: 技術分享
首部是一個非NULL變長字段長度列表,長度最大不超過2字節,第二部分是null標誌位。指示該行數據是否含有null值,有就用1表示,記錄頭信息固定占用5字節(40位),最後就是實際存儲每列的數據。特別註意,null不占用該部分不論什麽空間,除了占用null標誌位。還有就是每行數據除了用戶自己定義的以外,還包括隱藏列。事務id列和回滾指針列。各自是6字節和7字節的大小 ,假設沒有主見。每行還會添加一個6字節的rowid列。 3.2. redundant行記錄格式: 是mysql5.0版本號之前的行記錄存儲方式。之後仍然支持這個格式是為了兼容之前版本號的頁格式,其存儲方式例如以下: 技術分享


首部是一個字段長度偏移列表,也是依照列的順序逆序放置的,第二部分記錄頭信息占用6字節,最後就是實際存儲的每列的數據。
3.3. 行溢出樹據 innodb存儲引擎能夠將一條記錄的某些數據存儲在真正的數據頁面之外,一般將blob、lob這類的大對象列類型的存儲會把數據存放在數據頁面之外,可是,這樣的理解有點偏差。能夠將varchar列數據類型存放為行溢出數據,mysql數據庫的varchar類型能夠存放65535字節,可是實際上並不會存放65535字節。當中還有別的開銷。實際僅僅能存放65532字節。並且官方定義的65535長度是指全部varchar列的長度總和,假設列的長度總和超過這個長度。依舊無法創建。 Innodb存儲引擎的數據都是存放在頁類型的B-tree node中,可是當發生行溢出時,數據存放在頁類型為uncompress BLOB頁中。實際上僅僅有768字節的前綴數據保存在數據頁中,之後是偏移量。指向行溢出頁(uncompress BLOB page),那麽就引出多長的varchar是保存在單個數據頁中,從多長開始保存在BLOIB頁呢?思考:innodb是索引組織的。也就是B+ tree的結構。這樣每一個頁中至少有兩條行記錄(否則就失去了B+ tree的意義,變成鏈表了),因此假設一個頁僅僅能存放一條記錄,那麽innodb存儲引擎會自己主動將行數據存放在溢出頁中。 3.4 compressed和dynamic格式 inndob1.0.x開始引入新的文件格式,曾經支持的compact和redundant格式稱為antelope文件格式,新的文件格式稱為barracuda文件格式,barracuda文件格式擁有兩種新的行記錄格式:compressed和dynamic格式。 新的行記錄格式對於存放在BLOB中的數據採用了全然的行溢出方式,在數據頁中僅僅存放20字節的指針,實際的數據都存放在off page中(不同於compact和redundant格式會存放768個前綴字節), compressed另一個功能 就是存放在當中的數據會以zlib的算法進行壓縮,因此對於BLOB、text這類大長度數據可以進行很有效的存儲。
3.5 char的行結構存儲 存儲固定長度的字符類型,mysql4.1版本號開始char(N)中的N指的是字符的長度,而不是之前的字節的長度,因此在不同的字符集下。char類型相應的列內部存儲的可能不是定長的數據,因此對於多字節字符編碼的char類型的存儲,innodb在內部將其視為變長字符類型,

4.innodb數據頁結構 由下面7個部分組成: file header(文件頭):定長 38字節 page header(頁頭):56字節,用來記錄數據頁的狀態信息,0x45BF表示數據頁。 infimum和supermum records: 在每一個數據頁中有兩個虛擬的行記錄,用來限定記錄的邊界。infimum記錄是比該頁中不論什麽主鍵都要小的值。supermum records是比不論什麽可能大的值還要大的值,這兩個值在頁創建時被建立,而且不論什麽情況下不會被刪除,在兩種不同的行記錄格式下所占字節數不同。 user records(用戶記錄,即行記錄)和free space(空暇空間): free space是鏈表數組結構,在一條記錄被刪除後。該空間就會被增加到空暇鏈表中 page directory(頁文件夾): 存放了頁的相對位置,這些記錄指針有時候也稱為槽或者文件夾槽,在Innodb中。並非每條記錄擁有一個槽,innodb的槽是一個稀疏文件夾,即一個槽可能包括多個記錄。當記錄被刪除或者被插入時。須要對槽進行分裂或平衡的維護操作, file trailer(文件結尾信息):定長 8字節 為了檢測頁是否已經完整寫入了磁盤

InnoDB存儲引擎表的邏輯存儲結構