【问题标题】:What is stored in the leaf node of clustered index聚簇索引的叶子节点存储了什么
【发布时间】:2022-01-04 09:52:18
【问题描述】:

据我所知,在聚集索引的叶子节点中,表记录与主键一起存储。

但是我发现有些文章说主键是用真实记录的块地址而不是真实表记录来存储的。

你能告诉我哪个是正确的吗?

(1)存储块地址

(2)存储真实数据

【问题讨论】:

  • 据我了解,clustered 的索引存储在表文件中。如果不是,则创建一个单独的索引文件。 (他们以 MyISAM 为例)
  • 嗨@bato3 MyISAM 没有聚集索引
  • 是的,这就是我想写的。 MyISAM 不是clustered,并且总是在那里创建一个单独的索引文件。我建议做一个实验,看看它是否为 InnoDB 创建了一个附加文件。 CONSTRAINT pk PRIMARY KEY NONCLUSTERED (id)
  • 这个问题或许可以在 dba.stackexchange.com 上找到更好的答案。

标签: mysql database indexing b-tree clustered-index


【解决方案1】:

在mysql和innodb的上下文中,来自mysql官方页面 https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html

每个 InnoDB 表都有一个特殊的索引,称为聚集索引,用于存储行数据。

如果表很大,与使用与索引记录不同的页面存储行数据的存储组织相比,聚集索引架构通常会节省磁盘 I/O 操作。

基于以上事实,尤其是第 2 点,我相信第 2 点是正确的。从我的角度来看,原因是 (1)节省一次I/O。 如果叶子节点保存了页地址,就会多一次 I/O 来获取记录。

(2) 更高的可维护性。 如果发生分页,叶子节点只保存页地址,聚集索引更新记录数据页地址会很麻烦。

但是,我认为#1 有积分的原因是只保存地址比保存整行记录数据便宜,因此存储更多索引。

【讨论】:

  • 使用#1 可以更快地执行一些查询。但是(根据我的经验)这些情况是少数。也就是说,InnoDB 做出了“正确”的设计决策。
【解决方案2】:

请小心您阅读的内容。确保文章谈论“MySQL”及其主要“引擎”“InnoDB”。

主键存储的是真实记录的块地址,而不是真实的表记录。

在数据的 B+Tree 的每个叶节点(块)中存储了几行整行。该 BTree 由PRIMARY KEY 排序,它(显然)是该行的一部分。

唯一的“块地址”是两个图表中的链接。

我投票支持你的 2 号图表,附带以下条件:

  • 有一个 id=6 的 4 列行和 James, 37, LA 的其他列。
  • id=15 的行未完全显示。也就是说,您省略了其他 3 列。

一个“块”大小为 16KB,可以容纳 1 到数百行,具体取决于

  • 行的大小,
  • 行是否已被删除,留下“空闲”空间,
  • 等

(对于数据或索引,每块 100 行是一个简单的经验法则。)

【讨论】:

  • 感谢您的回答,我按照mysql和innodb的上下文中的方法找到了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多