在MySQL中(或者我应该说:使用MySQL的InnoDB引擎) - 如何表示空值?即,如果允许列有NULL
s,表(或记录级别的单个记录)的表示如何变化?
如果它对于不同的列数据类型有所不同 - 要么解释表示NULL的各种方法,要么只选择一种数据类型(例如INT
)。
答案 0 :(得分:3)
<强>参考强>
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位/ col,没有数据节省。
ROW_FORMAT=COMPACT
:
记录头的可变长度部分包含用于指示NULL列的位向量。如果索引中可以为NULL的列数是N,则位向量占用CEILING(N / 8)个字节。 (例如,如果有9到15列可以为NULL,则位向量使用两个字节。)NULL列不占用此向量中的位以外的空间。标题的可变长度部分还包含可变长度列的长度。每个长度需要一个或两个字节,具体取决于列的最大长度。如果索引中的所有列都是非NULL并且具有固定长度,则记录头没有可变长度部分。
即1位/ col,数据空间为零。
我怀疑,在没有证据的情况下,DYNAMIC
和COMPRESSED
就像COMPACT
。
列长
每列的前面都有1或2个字节的长度。 1或2的选择基于最大潜在列宽。 (注意:虽然LONGTEXT
需要4个字节的长度,但&#39;长度&#39;实际上是在讨论存储在记录中的数量,而不是溢出。)
溢出存储空间
当我谈论这个主题时,这里有一些关于&#34; long&#34; strings / blobs - 无论是在记录中还是存储在别处:
COMPACT
:长列为768 + 20 DYNAMIC
和COMPRESSED
:20列为长列&#34; 768&#34;表示文本/ blob的前768个字节存储在记录中; &#34; 20&#34;表示一个20字节的指针&#39;到其余(或全部)存储的位置。
KEY_BLOCK_SIZE
控制聚簇索引中存储的列数据量,以及溢出页面上的数据量。
(我要离开REDUNDANT
,因为我没有详细信息。)
经验法则
每个InnoDB行有20-30个字节的开销。
BTree(包括InnoDB的数据,加上每个二级索引)吸引了69%的满分作为块分割等。
&#34; Data_free&#34;可悲的是不完整;不相信它。
MyISAM非常简陋;很容易计算MyISAM表的空间。从那里,乘以2-3以获得InnoDB所需的空间。 (有例外,通常涉及MyISAM碎片,PK群集等)。
答案 1 :(得分:2)