1

我做了一个测试,以确保我知道 ENUM 是如何工作的以及它如何处理存储空间......并且得到了与预期不同的结果。

一张表,其中一个类型的字段VARCHAR(100)填充了 1,000,000 行。每行都有一个从 6 个字符串中随机选择一个的值,长度为 100。

然后,转换为ENUM,然后返回VARCHAR(100)。这是结果(数据大小)。

1. 1,000,000 行 = 99.2 MiB,VARCHAR(100)

2. 行 1,000,000 = 6,835.9 KiB,枚举 ('blah100Characters1','blah100Characters2',...,'blah100Characters6')

3. 行 1,000,000 99.2 MiB,VARCHAR(100)

按预期报告的VARCHAR(100)类型并匹配手册中的 MySQL 规范 ("L + 1 bytes, 0 <= L <= 255") 1,000,000 x 100 = 100,000,000 = 99.2 MiB

---编辑:嗯,加上一个额外的字节,但这与这个讨论无关:o)

但是,根据 ENUM 的 MySQL 规范(“1 或 2 个字节,取决于枚举值的数量(最大 65,535 个值)”),有 6 种可能的组合,我希望每行需要 1 个字节的数据. 1,000,000 x 1 = 1,000,000 = 976.5 KiB

谁能向我解释为什么转换后的表需要 6,835.9 KiB,奇怪的是,这几乎是预期的 7 倍?

4

1 回答 1

1

它加起来最多 7 个字节(我得到相同的结果);有些空间是填充,有些是删除标志。

要证明存在填充,请添加额外的枚举(或微小整数)。表的大小不会改变。

为了证明有删除标志,删除中间的一行。表的大小不会改变。

根据此页面,它与myisam_data_pointer_size默认值 6 字节(加上 1 字节用于删除)有关。

他似乎是正确的,好像我这样做:

alter table foo MAX_ROWS=10;

表的大小减小。

此外,从这个“错误”报告中,听起来好像一条已删除的记录被存储为指向下一条记录的指针。如果是这样,这意味着任何行的最小空间将是指针大小(默认为 6 个字节)加上一个删除字节。这是因为如果一条记录被删除,则设置删除字节,然后其他 6 个字节用于指向下一条记录。

如果您想了解更多信息,我会阅读 MyISAM 表的“删除链接链”(使用固定记录计数时)。

于 2012-08-17T04:09:41.983 回答