我了解 PostgreSQL 中基本的主键表存储,其中数据存储在页中,并使用 B 树索引结构进行高效检索。
但是,我想了解当表没有主键但在非主键列(例如列)上有索引时的行为name
。
CREATE TABLE products (
id SERIAL,
name VARCHAR(255) NOT NULL,
price DECIMAL(10, 2) NOT NULL
);
假设“products”表有100行,我的理解是数据将存储在页中,并且B树索引将有一个根节点[1, 100]
。
此外,还会有范围为[1, 49]
和 的中间节点[50, 100]
,它们将具有子节点,依此类推。但是,我不清楚索引的叶节点会发生什么。它们会包含实际的行数据吗?
如果
name
列上的索引没有主键,索引的叶节点将包含实际的行数据还是指向行的指针?如果叶节点包含实际的行数据,检索过程将如何工作?它会执行叶节点的线性扫描以找到所需的“名称”值吗?
另外,如果表已经在 上建立了索引
name
,那么拥有主键是否可以优化查询?
我希望详细解释此场景的存储和检索机制,以及任何相关的代码示例或其他注意事项。
我认为文档的这一部分回答了您的大部分问题。据我了解,不,我认为名称上有主键不会优化查询。主键约束不会影响名称列上的现有索引。但是,拥有主键可能会带来其他性能优势,例如,如果您需要在外键中引用产品表,则可以提高数据完整性和加快联接操作速度。
我认为你已经陷入了根本性的误解。PostgreSQL 表只是一组无序的行,它不按主键组织。主键索引与其他 B 树索引没有什么不同。B 树索引不通过主键引用表行,而是通过其
ctid
(当前元组 ID)引用表行,当前元组 ID 是 8kB 块号和块内条目号的组合。B 树索引
name
将存储实际的字符串,以树形有序列表的形式组织。叶节点包含ctid
引用的表行。