[英]How does MySQL/InnoDB represent NULL values internally?
在MySQL中(或者也許我應該說:使用MySQL的InnoDB引擎)-空值如何表示? 也就是說,如果允許列具有NULL
,那么表(或記錄為記錄級的單個記錄)的表示方式會如何變化?
如果不同的列數據類型不同,則說明每種表示NULL的方法,或者僅選擇一種數據類型(例如INT
)。
參考
https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html
行情和解釋
ROW_FORMAT=REDUNDANT
:
SQL NULL值在記錄目錄中保留一個或兩個字節。 除此之外,如果將SQL NULL值存儲在可變長度列中,則在記錄的數據部分中保留零字節。 在固定長度的列中,它在記錄的數據部分中保留列的固定長度。 保留NULL值的固定空間可以使列從NULL更新為非NULL值,而不會引起索引頁的碎片。
也就是說,NULL為1位/列,則不節省數據。
ROW_FORMAT=COMPACT
:
記錄頭的可變長度部分包含一個用於指示NULL列的位向量。 如果索引中可以為NULL的列數為N,則位向量占用CEILING(N / 8)個字節。 (例如,如果有9到15列可以為NULL的列,則位向量使用兩個字節。)NULL列不占用此向量中的位以外的空間。 標頭的可變長度部分還包含可變長度列的長度。 每個長度占用一個或兩個字節,具體取決於列的最大長度。 如果索引中的所有列都不為空並且具有固定長度,那么記錄頭將沒有可變長度部分。
也就是說,1位/列,零數據空間。
我懷疑沒有證據表明DYNAMIC
和COMPRESSED
就像COMPACT
一樣。
列長
每列前面都有1或2個字節的長度。 選擇1還是2是基於最大潛在列寬。 (注意:盡管LONGTEXT
需要4個字節的長度,但'length'真正的意思是存儲在記錄中的數量,而不是溢出)。
溢出存儲
當我在討論該主題時,以下是有關“長”字符串/ blob發生的情況的一些信息-無論是在記錄中還是存儲在其他位置:
COMPACT
:長COMPACT
768 + 20 DYNAMIC
和COMPRESSED
:長COMPRESSED
20 “ 768”表示文本/斑點的前768個字節存儲在記錄中; “ 20”表示剩余(或全部)存儲位置的20字節“指針”。
KEY_BLOCK_SIZE
控制在聚集索引中存儲多少列數據,以及在溢出頁面上放置多少列數據。
(我要離開REDUNDANT
出來的,因為我沒有細節。)
經驗法則
每個InnoDB行有20到30個字節的開銷。
當塊拆分時,BTree(包括InnoDB的數據,以及每個輔助索引)的容量已達到69%。
“ Data_free”非常不完整; 不要相信它。
MyISAM在太空領域是斯巴達式的。 計算MyISAM表的空間很容易。 從那里乘以2-3,以獲得InnoDB所需的空間。 (有一些例外,通常涉及MyISAM碎片,PK群集等)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.