【发布时间】:2021-02-01 14:38:53
【问题描述】:
我有这张桌子:
CREATE TABLE `tree_paths` (
`child_id` int(10) unsigned NOT NULL,
`parent_id` int(10) unsigned NOT NULL,
`sponsor_upline` tinyint(1) NOT NULL DEFAULT '0',
`left_leg` tinyint(1) NOT NULL,
`binary_level` smallint(5) unsigned NOT NULL DEFAULT '0',
`sponsor_level` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`child_id`,`parent_id`),
KEY `tree_paths_parent_id_foreign` (`parent_id`),
CONSTRAINT `tree_paths_child_id_foreign` FOREIGN KEY (`child_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `tree_paths_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
int(10) 消耗 4 字节,smallint(5) 2 字节,tinyint(1) 1 字节。因此,一行原始数据应该是 14 字节。
我插入了大约 1600 万行。由于某种原因,AVG 行长度是 57 字节而不是 14 字节。
主元组键的 B-tree 使用的存储量是数据本身的 3 倍,这是否现实?
另外,我在https://stackoverflow.com/a/30318725/2311074读到过
主键已计入 DATA_LENGTH。 INDEX_LENGTH 表示“所有二级索引的大小”。
如果是这样,那么为什么 index_length 是总大小的 1/4?如上所示,我没有辅助键。还是来自FOREIGN 键?
备注:
我发现了与我类似的问题。
一个是Why is InnoDB table size much larger than expected?,但它已经 10 岁了,我根本不明白。该问题的答案是隐藏的 6 字节列是造成差异的原因。但是,差异不是 6 而是 36。而且用户没有使用任何密钥,Index_length 仍然很大。所以我不知道这有什么意义,但我想 10 年前情况可能有所不同。
我发现的另一个答案是Average row length higher than possible。这个答案的重点是 InnoDb 只是分配了比它需要的更多的空间。但是,当我查看show table status 时,我发现我还有 7.3 MB 可用空间。所以看来我可以忽略这个。
【问题讨论】:
-
请注意,INT 声明后括号中的数字几乎没有意义
-
@Strawberry 它的显示宽度,对大小没有影响,对吧?
-
它(几乎)对任何东西都没有影响
-
@Strawberry 好的,很高兴知道 :)
-
@scaisEdge 是的,但我没有字符集字段,只有整数,所以没关系,对吧?