数据库如何修改磁盘上的索引?

时间:2017-07-29 19:00:11

标签: sql database postgresql

根据文档,每个PostgreSQL表都存储在一个单独的文件中。当表超过1 GB时,它将分为千兆字节大小的段。 (对于其他人来说,rdbms或多或少都是如此)

假设我正在更新位于文件中间的行。在没有丢失第二部分的情况下,无法在文件中间写入。如果我们将文件分成2部分,写一些数据,文件的第二部分应该复制到某处(在内存中或另一个文件中),然后附加到文件的第一部分。在这种情况下rdbms在内部做什么?

也许不是修改整个文件rdbms而是将修改后的行添加到文件中,并保持旧记录不被修改。如果这是真的,我对索引有同样的问题。如果发生b树插入,必须在文件的任意位置修改索引文件。 rdbms是否在每次更新/插入时重写整个索引文件?

1 个答案:

答案 0 :(得分:0)

评论太长了。

您对段大小的固定是有趣的错位。使用"段"分解单个文件在数据库中并不常见。在分配给一个或多个文件的表空间中存储数据的替代机制,其中一个物理文件存储来自多个表的页面也是常见的。还有其他替代方案(考虑柱状数据存储)。这是Postgres或任何其他数据库中存储机制中最不重要的部分。

通常,关系数据库在页面上存储表。 Postgres的页面布局在documentation中描述。最重要的是,这些是包含行(或行的一部分)的固定大小的块。

当在查询中引用页面时,它们被读入内存" 1"一次 - " 1"在引号中,因为相邻页面通常作为块读入。这些页面在内存缓存中进行管理,而查询需要这些页面,有时会根据需要换出或写入磁盘。

页面中可以包含空格。细分可以包含空白页面。插入记录时,它可能会出现在最后一页的末尾或某些较早的页面上,具体取决于空间和其他考虑因素。

索引也在页面上组织 - 事实上,使用相同的页面布局(虽然术语略有不同)。在索引中插入行的机制可能涉及创建新页面("页面拆分")或只是在现有页面上插入行。

这是一个高级别的描述。 Postgres是一个非常开放的数据库,其中详细记录了这些细节。其他数据库也做类似的事情,尽管从一个数据库到另一个数据库的细节确实不同。