空列值是否与填充列值占用相同的存储空间?


15

我有2列的表格。两列的类型均设置为varchar(38)。如果我为其中一列创建一个具有空值的行,它将占用与该值不为空相同的存储空间吗?

换句话说,在创建行时,MySQL是否会为列保留存储空间(取决于其类型)?

Answers:


11

Innodb物理行结构中,REDUNDANT ROW_FORMAT下的项目符号#7

SQL NULL值在记录目录中保留一个或两个字节。除此之外,如果将SQL NULL值存储在可变长度column中,则在记录的数据部分中保留零字节。在固定长度的列中,它在记录的数据部分中保留列的固定长度。保留NULL值的固定空间可以将列从NULL更新为非NULL值,而不会引起索引页的碎片。

Innodb物理行结构中,COMPACT ROW_FORMAT下的项目符号#2

记录头的可变长度部分包含一个用于指示NULL列的位向量。如果索引中可以为NULL的列数为N,则位向量占用CEILING(N / 8)个字节。(例如,如果有9到15列可以为NULL的列,则位向量使用两个字节。) NULL列不占用此vector中的位以外的空间。标头的可变长度部分还包含可变长度列的长度。每个长度占用一个或两个字节,具体取决于列的最大长度。如果索引中的所有列都不为空并且具有固定长度,那么记录头将没有可变长度部分。

根据这些要点,这是NULL列的存储占用的值

  • 可变长度:NULL值不占用行本身的存储空间
  • 固定长度:占用预留空间

现在,由于要指出的第一点,您必须在使用CHAR和VARCHAR之间做出选择

保留NULL值的固定空间可以将列从NULL更新为非NULL值,而不会导致索引页碎片

一旦存储了非NULL数据,这将防止引入行的任何碎片。这是我之前讨论过的有关MyISAM的问题:请参阅我的旧文章。在固定大小的字段上使用CHAR vs VARCHAR会对性能产生什么影响?


嗨,Rolando,我忘了提到另一件事,即varchar(5)和varchar(100)类型声明之间的内存分配差异。或实际上,过度分配会带来罚款。
Craig Efrein 2015年

@CraigEfrein您绝对应该在答案中添加内存分配。(顺便说一句,我已经支持您的回答了)
RolandoMySQLDBA

1
当您SELECT需要创建临时表的组合系统时,就会出现过度分配的问题。如果可能的话,它将使用MEMORY,并转换VARCHARCHAR对TMP表。现在VARCHAR(100)占用固定的100(或300)字节,从而可能减慢查询速度。
里克·詹姆斯

@RolandoMySQLDBA,您的答案中解释的行为是否适用于Mysql 5.7 DYNAMIC和COMPACT行格式。
Dinesh Kumar

@DineshKumar这些段落仍在5.7 / 8.0文档中。请参考dev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.html了解DYNAMIC。
RolandoMySQLDBA

8

无论您为varchar列定义的长度如何,一个空列使用的存储空间都将相同。

CHAR和VARCHAR类型

在此处输入图片说明

这仅解决varchar列使用的空间,而不考虑该行,其索引,主键和其他列使用的总存储空间。

正如ypercube在他的评论中提到的那样,当存在至少一个可空列时,整个行还需要考虑其他事项。

Innodb物理行结构

记录头的可变长度部分包含一个用于指示NULL列的位向量。如果9到15列之间的任何地方都可以为NULL,则位向量使用两个字节。)

...

标头的可变长度部分还包含可变长度列的长度。每个长度占用一个或两个字节,具体取决于列的最大长度。如果索引中的所有列都不为空并且具有固定长度,那么记录头没有可变长度部分

是的,使用的存储空间会根据您选择的类型(固定的还是可变的),排序规则和其他因素(例如引擎)而变化。

MySQL在此处提出有关优化数据存储的建议:优化数据大小

更新资料

使用varchar的另一项考虑是内存。在MySQL中,尽可能限制可变长度列的大小很重要。即使该列是可变的并且使用的存储空间是可变的,MySQL也会以固定块的形式分配内存来存储值。例如,varchar(200)将使用比varchar(5)更多的内存。这不是存储空间问题,但在定义列时仍要考虑一些问题。


上面的数字假定为CHARACTER SETlatin1或ascii。对于UTF8,存储要求CHAR(4)是12
瑞克·詹姆斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.