主要介紹InnoDB存儲引擎表的邏輯存儲以及實現。重點介紹數據在表中是如何組織和存放的。
1.索引組織表(index organized table)
在InnoDB存儲引擎中,表都是根據主鍵順序組織存放的,這種存儲方式的表叫索引組織表。在InnoDB存在引擎表中,每張表都有個主鍵(Primary key),如果在創建表時沒有顯示定義主鍵,則會按照如下方式選擇或者創建主鍵:a.判定是否有非空的唯一索引(unique not null),如果有則該列即為主鍵。若果有多個,則選擇建表是第一個定義的非空位於索引為主鍵。注意:主鍵的選擇根據的是定義索引的順序,而不是建表時的列的順序。 b.如果不存在唯一索引,InnoDB存儲引擎字段創建一個6字節大小的指針。
2.InnoDB邏輯存儲結構
在InnoDB存儲引擎中,所有的數據都被邏輯地存放在一個空間中,稱之為表空間(tablespace)。表空間又由段(segment)、區(extent)、頁(page)組成。頁在一些文檔中有時也稱之為塊(block)。InnoDB存儲引擎的邏輯存儲結構如下圖。
vc/M2Mri0tS689TavenJ3KGjts62vMrH0v3H5tfUye253MDttcShozxicj4KICAgIEMux/g8YnI+CiAgICAgICAgx/jKx9PJwazQ+NKz1+mzybXEv9W85KGjSW5ub0RCtOa0otL9x+bSs7XEtPPQoc6qMTZLQqOs0ru49sf409A2NLj2wazQ+LXE0rPX6bPJo6zL+dLUw7+49sf4tcS089ChtrzKxzFNQqGjSW5ub0RCIDEuMC54sOaxvr+qyrzS/cjr0bnL9dKzo6y8tMO/uPbSs7XEtPPQob/J0tTU2r2ose3Ksc2ouf2yzsr9a2V5X2Jsb2NrX3NpemXJ6NbDzqoyS6GiNEuhojhLo6zS8rTLw7+49sf4ttTT2tKztcTK/cG/vs3OqjUxMqGiMjU2oaIxMjaho0lubm9EQiAxLjIuWLDmsb7QwtT2ss7K/Wlubm9kYl9wYWdlX3NpemW9q8SsyM/Ss7XEtPPQocno1sPOqjRLoaI4S6OstavKx9Kz1tC1xMr9vt2yu8rH0bnL9aOs1eLKx8f41tC1xMr9wb/NrNH5zqoyNTahojEyOKGj0ru+5Luwo6yyu8Lbwta1xLTz0KHU9cO0seS7r6Osx/i1xLTz0KGyu7HkMU2ho7WrysfT0NXi0fnSu7j2zsrM4qO61Nq/qsb0tsDBorHtv9W85NauuvOjrLS0vai1xLHtxKzIz7Tz0KHKxzk2S6Osx/jW0MrHNjS49sGs0Pi1xNKzo6y0tL2otcSx7b/VvOTTprjDyscxTbLFttTRvaO/1eLKx9LyzqrU2sO/uPa2zrXEv6rKvMqxo6zPyNPDMzK49tKztPPQobXEy+nGrNKzKGZyYWdtZW50CiBwYWdlKcC0saO05sr9vt2jrNTayrnTw83q1eLQqdKz1q6687LFysc2NLj2wazQ+LXE0rO1xMnqx+uho9Xi0fnX9srHttTT2tK70KnQobHtu/LV33VuZG/V4sDgtcS2zqOsv8nS1NTav6rKvMqxyerH673Pydm1xL/VvOSjrL3ayqG0xcXMyN3Bv7XEv6rP+qGjPGJyPgogICAgRC7Sszxicj4KICAgICAgICDSs8rHSW5ub0RCtMXFzLncwO21xNfu0KG1pc67oaPErMjPtPPQoc6qMTZLo6y/ydLUzai5/Wlubm9kYl9wYWdlX3NpemW9q9KztcS089ChyejWw86qNEuhojhLoaIxNkujrNTyy/nT0LHt1tDSs7XEtPPQoba8zqrJ6NbDJiMyMDU0MDujrLK7v8nS1LbUxuTU2bTO0N64xKGjs/23x82ouf1teXNxbGR1bXC1vMjrus21vLP2stnX98C0svrJ+tDCtcS/4qGjs6O8+7XE0rO1xMDg0M3T0DrK/b7d0rMoQi10cmVlIE5vZGUpoaJ1bmRv0rModW5vZCBMb2cgUGFnZSmhos+1zbPSsyhTeXN0ZW0gUGFnZSmhosrCzvHK/b7d0rMoVHJhbnNhY3Rpb24gc3lzdGVtIFBhZ2UpoaKy5cjru7qz5b/Vz9DB0LHt0rMoSW5zZXJ0IEJ1ZmZlciBGcmVlIExpc3QpoaLOtNG5y/W1xLb+vfjWxrTzttTP89KzKFVuY29tcHJlc3NlZAogQkxPQiBQYWdlKaGi0bnL9bXEtv69+NbGttTP89KzKGNvbXByZXNzZWQgQkxPQiBQYWdlKTxicj4KICAgIEUu0NA8YnI+CiAgICAgICAgSW5ub0RCtOa0otL9x+bKx8Pmz/LQ0LXEKHJvdy1vcmllbnRlZCmjrNKyvs3Kx8u1yv2+3crHsLTQ0L340NC05rfFtcSho8O/uPbSs7Tmt8W1xNDQvMfCvNKyysfT0NOy0NS2qNLltcSjrNfutuDUy9DQtOa3xTE2Sy8yLTIwMNDQtcS8x8K8o6y8tDc5OTLQ0LzHwryhozwvcD4KCjxwPjMuSW5ub0RC0NC8x8K8JiMyNjY4NDvKvTxicj4KICAgIElubm9EQrTmtKLS/cfmtcS8x8K8ysfS1NDQtcTQzsq9tOa0orXEo6zV4r7Nse3D99Kz1tCxo7Tm18Wx7dbQ0rvQ0NDQtcTK/b7doaPG5MDg0M3T0FJFRFVOREFOVKGiIENPTVBBQ1ShokNPTVBSRVNToaJEWU5BTUlDy8TW1qGjv8nS1M2ouf1zaG93ICB0YWJsZSBzdGF0dXM7wLSy6b+0tbHHsL/i1tDDv9XFse21xMr9vt0mIzI2Njg0O8q9yOfPws28Ojxicj4KICAgPGltZyBzcmM9"http://www.2cto.com/uploadfile/Collfiles/20141202/20141202092356171.jpg" alt="\">
A.COMPACT
在MySQL 5.0中引入,其設計目標是高興的存儲數據。也就是一個頁中存放的行數據越多,其性能越高。compact行記錄的存放方式:
有圖可知,compact行記錄格式的首部是一個非NULL變長字段長度列表,並且其是按照列的順序逆序放置的,其長度為:
若列的長度小於255個字節,用1字節表示;
若大於255個字節,用2字節表示。
變長字段之後的第二個部分是NULL標志位,該位置指示了該行數據中是否有NULL值,有這用1表示。該部分占1個字節。接下來就是占用5個字節的記錄頭信息(record header),每位的含義如下圖:
最後的部分就是實際存儲每列的數據。注意NULL不占該部分的任何空間,也就是說NULL除了占有NULL標志位,實際存儲不占任何空間。每行除了用戶定義的列外,還有2個隱藏列(事務ID列(6字節)和回滾指針列(7字節))。若InnoDB表沒有定義主鍵,還會增加一個6字節的rowid列。不管是char類型還是varchar類型,在compact格式下NULL值都不占用任何存儲空間。
COMPACT行格式特點:
每個也記錄都有5字節長度域,用於指向下一個連續的頁,並且可用於實現行鎖
有個變長域,存儲頁中有多少可能為NULL的字段數,長度為 CEILING(N/8)字節,同時也需要用1~2字節存儲邊長字段所需長度
所有非NULL的變長字段,用1~2字節存儲其長度信息
行記錄頭部域之後,緊跟著就是所有非NULL的字段
UTF8字符集的CHAR(N)字段,優先刪除末尾空格,嘗試用N字節存儲,並且再預留N個字節用於後續數據更新,避免產生碎片
B.REDUNDANT
redundant是MySQL 5.0版本之前InnoDB的行記錄存儲方式。如圖:
redundant行記錄格式的首部是一個字段長度偏移列表,同樣是按照列的順序逆序放置的。若列的長度小於255字節,用1字節表示;若大於255字節,用2字節表示。第二個部分記錄頭信息(record header)。如下圖:
最後的部分就是時間存儲的每個列的數據。
REDUNDANT行格式特點:
每個頁包含6字節ROWID,用於指向下一個連續的頁,並且可用於實現行鎖
聚集索引中包含所有字段,並且包含額外的6字節TRX_ID,和7字節ROLL_PTR
如果沒顯式主鍵,則使用隱含的6字節ROWID作為主鍵
行記錄中存儲指向全部字段的指針,字段長度小於128字節時,該指針占用1字節,否則需要2字節
類似CHAR的定長類型字段,也采用固定寬度存儲,並且不刪除末尾的空格
類似VARCHAR變長類型字段中NULL不會占用實際存儲空間,而CHAR定長類型字段中,NULL則占用相應的字節數
C.行溢出數據
InnoDB存儲引擎可以將一條記錄中的某些數據存儲在正在的數據頁之外。一般認為BLOB、LOB這類的大對象類型的存儲會把數據存放在數據頁面之外。這個理解有點偏差,BLOB等可以不將數據房子溢出頁面,而且即使是varchar列數據類型依然有可能被存放為行溢出數據。這個主要取決於實際存放的數據。
D.COMPRESS和DYNAMIC
innodb 1.0.x版本引入了新的文件格式(file format),以前支持的compact和redundant格式稱為Antelope文件格式,而新的文件格式稱為Barracuda文件格式。其Barracuda包括兩種新的行記錄格式:Compressd和Dynamic。新的兩種記錄格式對呀存放在BLOB中的數據采用完全的行溢出的方式,在數據頁中只存放20個字節的指針,時間的數據存放在Off Page中。而之前的Compact和Redundant會存放錢768個前綴字節
COMPACT與REDUNDANT的區別
COMPACT相比REDUNDANT約可節省20%左右, COMPRESS相比COMPACT約可節省50%左右,但會導致CPU消耗增加,TPS可能只有原來的10%
類似CHAR的定長類型,也采用固定寬度存儲,並且不刪除末尾的空格(VARCHAR則會刪除空格)
所有輔助索引存儲了那些在主鍵定義中存在,但不在輔助索引中存在字段(提高輔助索引檢索效率)
DYNAMIC、COMPRESSED格式中,長字段只存儲20字節,其余全部off-page(實際長度40字節以內的,則不會發生off-page,哪怕是text/blob)
未完待續。。。