sanjihan Asked: 2019-09-05 01:15:42 +0800 CST2019-09-05 01:15:42 +0800 CST 2019-09-05 01:15:42 +0800 CST InnoDB 中记录指针的大小? 772 我正在尝试按比例增加冗余属性和性能增益。尽管存储冗余信息会导致许多异常,但我只关注冗余属性的大小与在不同表中存储指向另一个元组的指针(或引用)。 那么InnoDB Mysql系统中元组指针的大小是多少呢?我发现 MyISAM 使用 6 个字节。InnoDB 也一样吗?作为参考,6 个字节使得在单独的表中存储 3 个 SMALLINT(每个 2 个字节)在存储方面毫无意义。也许一个等价的问题是:记录地址的大小是多少? mysql innodb 1 个回答 Voted Best Answer Rick James 2019-09-05T09:26:26+08:002019-09-05T09:26:26+08:00 MyISAM默认为索引中的数据指针使用 6 个字节。索引指针默认为 5 个字节。您所指的“6”是从 .MYI 文件到 .MYD 文件的字节偏移量。这不一定与您的其他问题相关。 InnoDB 要复杂得多。它不使用指针,只使用列。 数据存储在按 .排序的 BTree 中PRIMARY KEY。(实际上是一个 B+树。) 二级索引存储在单独的 BTree 中,每个节点记录中都有 PK。 FK 只是指示的列,用于在其他表中的合适索引中进行查找。 id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY 占用 1 个字节,加上一些开销 id VARCHAR(255) CHARSET utf8mb4 PRIMARY KEY, stuff1 VARCHAR(255) CHARSET utf8mb4, stuff2 VARCHAR(255) CHARSET utf8mb4, INDEX(stuff1, stuff2) 最后这个二级索引占用了 3*(2+255)*4+? 字节—— 3 列(stuff1、stuff2、id) 2——长度 255 -- utf8mb4的最大字符长度 4 -- utf8mb4 中的最大字节/字符 +?-- 有开销;这各不相同。 回到“指针”。在较低级别有一些“指针”: 4 字节块指针(16KB 块),因此表大小限制为 64TB。 指向溢出数据的 20 字节指针(用于指向一个大的TEXT或BLOB. 块内的一些 1 字节和 2 字节长度或指针。 ?交易 ID 的字节数。(参见 MVCC 等) 根据经验,InnoDB 表占用的磁盘空间是等效的 MyISAM 表的 2-3 倍。 那么InnoDB Mysql系统中元组指针的大小是多少呢? 如果TINYINT UNSIGNED足够(另一个表中最多 255 个项目),则将其视为每个表中的 1 个字节,再加上目标表中每个辅助键的 1 个字节。 INT经常使用(通常有超过 20 亿的限制),将其视为每个 4 个字节。 也许一个更重要的问题是是否在AUTO_INCREMENT表上有一个“代理”( ) id。统计这个表和其他表的引用次数,判断它的大小。并使用其中最小的味道INT是安全的。 这带来了 ids 的“燃烧”。在几乎所有情况下,INSERT(及其变体)将首先分配它可能需要的 auto_inc id。如果它没有全部使用它们(例如 for INSERT IGNORE),则 ID 将丢失(烧毁)。这可能导致耗尽,TINYINT比预期快得多。对于批量标准化,我提供了这种技术:http: //mysql.rjweb.org/doc.php/staging_table#normalization
MyISAM默认为索引中的数据指针使用 6 个字节。索引指针默认为 5 个字节。您所指的“6”是从 .MYI 文件到 .MYD 文件的字节偏移量。这不一定与您的其他问题相关。
InnoDB 要复杂得多。它不使用指针,只使用列。
数据存储在按 .排序的 BTree 中
PRIMARY KEY
。(实际上是一个 B+树。)二级索引存储在单独的 BTree 中,每个节点记录中都有 PK。
FK 只是指示的列,用于在其他表中的合适索引中进行查找。
占用 1 个字节,加上一些开销
最后这个二级索引占用了 3*(2+255)*4+? 字节——
回到“指针”。在较低级别有一些“指针”:
TEXT
或BLOB
.根据经验,InnoDB 表占用的磁盘空间是等效的 MyISAM 表的 2-3 倍。
TINYINT UNSIGNED
足够(另一个表中最多 255 个项目),则将其视为每个表中的 1 个字节,再加上目标表中每个辅助键的 1 个字节。INT
经常使用(通常有超过 20 亿的限制),将其视为每个 4 个字节。也许一个更重要的问题是是否在
AUTO_INCREMENT
表上有一个“代理”( ) id。统计这个表和其他表的引用次数,判断它的大小。并使用其中最小的味道INT
是安全的。这带来了 ids 的“燃烧”。在几乎所有情况下,
INSERT
(及其变体)将首先分配它可能需要的 auto_inc id。如果它没有全部使用它们(例如 forINSERT IGNORE
),则 ID 将丢失(烧毁)。这可能导致耗尽,TINYINT
比预期快得多。对于批量标准化,我提供了这种技术:http: //mysql.rjweb.org/doc.php/staging_table#normalization