[英]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.