TL;DR 版本 - 无论 DBMS 实现如何,您的键值始终存储在磁盘上。
PostgreSQL 将在磁盘上的页面中存储 4 行,每一行用于您插入的每一行。SQL Server 还将在磁盘上存储 4 行。B树是查找结构,不是页级存储结构。
在底层磁盘级别,PostgreSQL 使用无序磁盘结构来存储数据。发生这种情况是因为由于 MVCC 事务语义,PostgreSQL 可能在任何给定时间维护行的多个副本。每行都有一个 xmin 和 xmax 详细说明当前行的创建和销毁事务 ID。autovacuum 进程执行幽灵记录清理操作。PostgreSQL 中的索引指向堆表结构中的行。这组幻灯片详细介绍了该过程。特别是,您需要查看幻灯片 29 以了解 b-tree 查找是如何发生的,以及查看幻灯片 48-52 以了解数据如何存储在磁盘上的理论讨论。
在 SQL Server 中,您将在叶页上有记录,但只有四行聚集索引将只有 1 个索引级别 - 叶级别。您可以通过运行来验证这一点SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('dbo.Tree'), NULL, NULL, NULL)
。您还可以通过以下方式验证 SQL Server 中的物理页面级别:
-- Locate the first page of the index
DBCC IND('test', 'Tree', 1);
GO
-- tell SQL Server to show DBCC output in the message page, not the SQL Server log
DBCC TRACEON (3604);
GO
-- look at nasty, dirty, on page data.
DBCC PAGE(test, 1,155,3);
一旦你看到 DBCC PAGE 输出,你就会恨我。最后,您应该会看到四行如下所示:
Slot 0 Offset 0x60 Length 15
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP Record Size = 15
Memory Dump @0x000000006D6FA060
0000000000000000: 10000c00 01000000 01000000 020000††††...............
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
Key = 1
Slot 0 Column 2 Offset 0x8 Length 4 Length (physical) 4
ID = 1
Slot 0 Offset 0x0 Length 0 Length (physical) 0
KeyHashValue = (e2338e2f4a9f)
这是 SQL Server 存储的实际行数据。您将在整个输出中看到 Key = 1 的多个副本,然后是 ID 信息。可以在此处找到这些命令的支持信息。
PostgreSQL 和 SQL Server 之间差异背后的原因来自 PostgreSQL 的 MVCC 实现。由于我们在 PostgreSQL 中可能有多个行的副本,因此最好将数据的多个副本保留在磁盘上,而不是修改支持的索引结构。只要有可能,PostgreSQL 就会进行仅堆更新,并且只在基础表上发布更新。SQL Server 做同样的事情,只有在可以避免更新支持的索引时才会更新聚集索引(或堆)。