簡體   English   中英

MySQL / InnoDB如何在內部表示NULL值?

[英]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位/列,零數據空間。

我懷疑沒有證據表明DYNAMICCOMPRESSED就像COMPACT一樣。

列長

每列前面都有1或2個字節的長度。 選擇1還是2是基於最大潛在列寬。 (注意:盡管LONGTEXT需要4個字節的長度,但'length'真正的意思是存儲在記錄中的數量,而不是溢出)。

溢出存儲

當我在討論該主題時,以下是有關“長”字符串/ blob發生的情況的一些信息-無論是在記錄中還是存儲在其他位置:

  • <= 40字節(在給定的列中):存儲在記錄中。
  • 如果整個記錄適合大約8KB:將存儲在記錄中。
  • 否則, COMPACT :長COMPACT 768 + 20
  • 否則, DYNAMICCOMPRESSED :長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群集等)

這僅適用於COMPACT(冗余僅出於歷史原因才很有趣,除非您訪問字典表)。 對於每個可為NULL的列,NULLS標頭中只有一位。

如果表中沒有可為空的字段,則NULL頭大小為零。

如果列值為NULL,則該位置1,並且記錄數據中沒有值。

如果列值不為NULL,則該位未設置,並且該列值存儲在記錄的數據中。

以COMPACT格式記錄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM