【问题标题】:How does MySQL/InnoDB represent NULL values internally?MySQL/InnoDB 如何在内部表示 NULL 值?
【发布时间】:2017-08-27 20:25:57
【问题描述】:

在 MySQL 中(或者我应该说:使用 MySQL 的 InnoDB 引擎)- null 值如何表示?即,如果允许列具有NULLs,则表(或单个记录,如果它在记录级别)的表示如何变化?

如果不同的列数据类型不同 - 请解释表示 NULL 的各种方法,或者只选择一种数据类型(例如INT)。

【问题讨论】:

    标签: mysql innodb


    【解决方案1】:

    参考

    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 的列不占用此向量中的位以外的空间。标题的可变长度部分还包含可变长度列的长度。每个长度占用一个或两个字节,具体取决于列的最大长度。如果索引中的所有列都不是 NULL 并且具有固定长度,则记录头没有可变长度部分。

    即 1 位/列,数据空间为零。

    我怀疑,没有证据,DYNAMICCOMPRESSED 就像 COMPACT

    列长

    每列前面都有 1 或 2 字节长度。 1 或 2 的选择基于最大潜在列宽。 (注意:虽然LONGTEXT 需要 4 字节长度,但“长度”实际上是指存储在记录中的数量,而不是溢出。)

    溢出存储

    当我谈到这个话题时,这里有一些关于“长”字符串/blob会发生什么的信息——无论它是在记录中,还是存储在其他地方:

    • 如果整条记录大约 8KB:存储在记录中。
    • 否则,COMPACT: 768+20 用于长列
    • 否则,DYNAMICCOMPRESSED:长列为 20

    “768”表示text/blob的前768个字节存储在记录中; “20”表示一个 20 字节的“指针”,指向其余部分(或全部)的存储位置。

    KEY_BLOCK_SIZE 控制在聚集索引中存储多少列数据,以及在溢出页上放置多少。

    (我不知道REDUNDANT,因为我没有详细信息。)

    经验法则

    每个 InnoDB 行有 20-30 字节的开销。

    BTree(包括 InnoDB 的数据,加上每个二级索引)随着块拆分等被吸引到 69%。

    “Data_free”非常不完整;不要相信它。

    MyISAM 在太空方面非常简陋;计算 MyISAM 表的空间很容易。从那里乘以 2-3 以获得 InnoDB 所需的空间。 (也有例外,常涉及MyISAM分片、PK集群等)

    【讨论】:

    • ...磁盘存储和内存表示之间是否相同?即从磁盘加载数据时是否发生任何解析/格式/布局更改?
    • 缓存(在 RAM 中)和磁盘之间的存储是相同的,除了一个例外:ROW_FORMAT=COMPRESSED 已在磁盘上压缩,但在缓存中压缩和未压缩 - 使其(在我看来)不值得用于大多数情况。这种压缩(某种程度上)是在块级别,而不是单个列。
    【解决方案2】:

    这仅适用于 COMPACT(REDUNDANT 仅出于历史原因感兴趣,除非您访问字典表)。 对于每个可 NULL 列,NULLS 标头中都有一位。

    如果表中没有可 NULL 字段,则 NULL 标头大小为零。

    如果列值为NULL,则设置该位并且记录数据中没有值。

    如果列值不为 NULL,则该位未设置,列值存储在记录的数据中。

    【讨论】:

      猜你喜欢
      • 2012-10-03
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 2018-06-13
      • 2010-11-23
      • 2011-02-28
      • 1970-01-01
      相关资源
      最近更新 更多