InnoDB字段类型大小vs文件大小是否降低?

时间:2019-07-05 18:49:49

标签: mysql innodb

我创建了这些表:

create table aca (money TINYINT);
create table acb (money SMALLINT);
create table acc (money INT);
create table acd (money BIGINT);

我反复运行以下插入以添加9420行:

INSERT INTO aca (money) VALUES(7), (8), (9), (10), (12);
INSERT INTO acb (money) VALUES(7), (8), (9), (10), (12);
INSERT INTO acc (money) VALUES(7), (8), (9), (10), (12);
INSERT INTO acd (money) VALUES(7), (8), (9), (10), (12);

当我检查服务器上的文件时,它显示每个数据库都比另一个大:

-rw-r----- 1 mysql mysql 360448 Jul  5 14:21 aca.ibd
-rw-r----- 1 mysql mysql 376832 Jul  5 14:21 acb.ibd
-rw-r----- 1 mysql mysql 393216 Jul  5 14:21 acc.ibd
-rw-r----- 1 mysql mysql 442368 Jul  5 14:21 acd.ibd

由于每个字段的大小是下一个字段的两倍,所以我希望每个数据库文件的大小大约是它的两倍(由于标题而造成的细微差别),但是事实并非如此,而是大小是两倍(增大100%),增大了4-13%。

为什么?

1 个答案:

答案 0 :(得分:3)

InnoDB表中包含什么?这是一个粗略的列表:

  • 由于您没有PRIMARY KEY,所以会添加一个隐藏的6字节数字。
  • 每列前面都有一个长度和空信息。在您的情况下,这可能会每行增加2个字节。
  • 每一行都有各种各样的开销,包括事务之类的东西。一个估计是每行29个字节。
  • BTree的填充量不超过15/16。 (15KB / 16KB)。

同时,典型表定义的便捷经验法则是将明显的总列大小乘以2至3,以获得.ibd文件的大小。这不适用于您的情况,因为您的列数极少(1)。

仅查看基本的,恒定的开销:

9420 * 16/15 * (29+6) = 351KB

该数字非常适合作为您获得的表大小的下限。

另一个问题:在某个时候,InnoDB会抢占4/8 / 16MB的空间(“范围”)(我不确定它的大小)。我想你还没有实现。发生这种情况时,计算将变得更加混乱并且难以遵循。

可以说,InnoDB进行了一些折衷。他们“浪费”了一些空间(有时很多空间),以使处理过程更简单,更快捷。

如果您有PRIMARY KEY,则15/16会成为问题。如果按PK顺序插入,则15/16棍。但是,如果您随机插入,则下降到大约69%。这是因为块分裂。

哦,“大”文本/ blob列成为“未记录”。 ROW_FORMAT会增加皱纹。

而且,如果您使用MyISAM进行此操作,则会得到令人困惑的尺寸,例如75360、75360、75360和94200。这些解释起来非常简单,而且,如果我理解正确的话,很容易预测。

困惑了吗?