主键索引的类型以及在 MySQL 中修改它们会发生什么

Type of primary key index and what happens on modifying them in MySQL

评分最高的答案 here 提到 MySQL 中的记录是如何按主索引的顺序存储的。这是否意味着创建的主索引是 sparse 索引?如果是这样,如果通过更改构造主键的列或修改其中一个条目来修改主键,会发生什么情况。

很抱歉在同一个 post 中问了 2 个问题,但我认为最好一起问。我在处理查询时非常慢的 tables 时遇到了这个疑问,所以我想也许以某种方式插入行是基于 table 中的实际列会有所帮助。

我将回答有关 MySQL 的默认存储引擎 InnoDB 的问题。这是您应该为 MySQL 中的所有 table 使用的存储引擎,除非您有非常具体的原因不这样做。

问题一的答案:主键不是稀疏索引。我知道该术语指的是仅对 table 中的部分行具有值的索引。 IE。带有 WHERE 子句的索引。但是主键必须占table中的所有行。如果您需要唯一地引用任何一行,它就是您使用的一列或多列。

尽管聚簇索引是按主键值顺序存储的,但它不一定按主键值的顺序存储在磁盘上。 InnoDB tablespace 中的每个页面都有一个 link 到“下一页”,该页面可能不会在物理上紧随其后。它可能在文件的后面,甚至更早。这些页面可能散布着其他索引的页面(如果您使用共享 tablespace,甚至其他 table)。这就是你所说的稀疏索引吗?

问题 2 的答案:如果更改 table 的主键的列,则必须重构 table 的存储。 InnoDB 使用主键作为 聚集索引 ,这意味着其余列与 B-tree 数据结构的叶节点一起存储。更改主键列可能会更改存储顺序,以及每个 B-tree 节点(内部节点和叶节点)的大小。

这意味着当您重组主键时,您的服务器暂时需要大量额外存储空间 space — 最多是 table 大小的两倍。重组完成后,旧版本的 table 将自动删除。