在MySQL中(或者我應該說:用MySQL的InnoDB引擎) - 空值是如何表示的?即如果允許列具有NULL
s,那麼表格(或者如果它在記錄級別上是單個記錄)的表示如何改變?MySQL/InnoDB如何在內部表示NULL值?
如果不同的列數據類型不同 - 要麼解釋表示NULL的各種方法,要麼選擇一種數據類型(例如INT
)。
在MySQL中(或者我應該說:用MySQL的InnoDB引擎) - 空值是如何表示的?即如果允許列具有NULL
s,那麼表格(或者如果它在記錄級別上是單個記錄)的表示如何改變?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值,而不導致索引頁的碎片化。
也就是說,1位/列用於NULL,不節省數據。
ROW_FORMAT=COMPACT
:
記錄標題的可變長度部分包含用於指示NULL列的位向量。如果索引中可以爲NULL的列數爲N,則該位向量佔用CEILING(N/8)個字節。 (例如,如果有9到15列的任何地方可以爲NULL,則位向量使用兩個字節。)NULL的列不佔用此向量中的位以外的空間。標題的可變長度部分也包含可變長度列的長度。每個長度需要一個或兩個字節,具體取決於列的最大長度。如果索引中的所有列都不是NULL並且具有固定長度,則記錄標頭不包含可變長度部分。
也就是說,1位/列,零空間的數據。
我懷疑,沒有證據,DYNAMIC
和COMPRESSED
就像COMPACT
。
柱長
每一列都具有在它前面的一個1-或2-字節長度。 1或2的選擇基於最大電位列寬。 (注意:儘管LONGTEXT
需要4個字節的長度,但「長度」實際上是指存儲在記錄中的數量,而不是溢出。)
溢出存儲
雖然我的話題,在這裏是什麼與「長」串/斑點發生的一些信息 - 無論是在記錄或存儲在別處:
COMPACT
:768 + 20長列DYNAMIC
和COMPRESSED
:20長列「768」 是指該第一768個字節的文本/斑點的存儲在記錄中; 「20」表示一個20字節的「指針」,指向其餘(或全部)存儲的位置。
KEY_BLOCK_SIZE
控制聚集索引中存儲了多少列數據,以及溢出頁面上放置了多少列數據。
(我離開REDUNDANT
出來的,因爲我沒有細節。)拇指
沒有爲每個InnoDB的行20-30個字節的開銷的
規則。
B樹(包括數據InnoDB的,再加上每個副指數)在重力作用下,以69%爲完全分裂塊等
「Data_free」是遠遠不完全;不要相信它。
MyISAM在空間上非常簡潔;計算MyISAM表的空間很容易。從那裏,乘以2-3來獲得InnoDB所需的空間。 (也有例外,通常涉及到MyISAM碎片,PK集羣等)
...在磁盤存儲和內存中表示之間是相同的嗎?即從磁盤加載數據時是否發生任何解析/格式/佈局更改? – einpoklum
緩存(在RAM中)和磁盤之間的存儲是一樣的,但有一個例外:'ROW_FORMAT = COMPRESSED'在磁盤上壓縮,但在緩存中壓縮和解壓縮 - 使得它在我看來不適用於大多數情況。該壓縮是在塊級上的(有點),而不是單個的列。 –