繁体   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