我做了一个测试,以确保我知道ENUM如何工作以及它如何处理存储空间...并得到与预期不同的结果。
一个表格,其中一个字段VARCHAR(100)
填充了1,000,000行。每行都有一个从6个字符串中的1个中随机选择的值,长度为100。
然后,转换为ENUM
,然后转换回VARCHAR(100)
。以下是结果(数据大小)。
1。行1,000,000 = 99.2 MiB,VARCHAR(100)
2。行1,000,000 = 6,835.9 KiB,Enum ( 'blah100Characters1', 'blah100Characters2',..., 'blah100Characters6')
第3。行1,000,000 99.2 MiB,VARCHAR(100)
VARCHAR(100)
类型按预期报告并匹配手册中的MySQL规范(“L + 1字节,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倍?
答案 0 :(得分:0)
它最多增加7个字节(我得到相同的结果);一些空间是填充,一些是删除标记。
要证明存在填充,请添加其他枚举(或微小整数)。表的大小不会改变。
要证明存在删除标记,请删除中间的行。表的大小不会改变。
根据this page,它与myisam_data_pointer_size
的默认值为6个字节(加上1个字节用于删除)。
他似乎是正确的,好像我这样做:
alter table foo MAX_ROWS=10;
表的大小减少。
此外,从this "bug" report开始,听起来像删除的记录被存储为指向下一条记录的指针。如果是这样,那意味着任何行的最小空间将是指针大小(默认为6个字节)加上删除字节。这是因为如果删除记录,则设置删除字节,然后使用其他6个字节指向下一条记录。
如果您想了解更多信息,我会阅读MyISAM表的“删除链接链”(使用固定记录计数时)。