Iam*_*mIC 3 database sql-server postgresql b-tree
我知道SQL Server可以在聚簇索引中以叶级别存储行的数据.我相信PostgreSQL不会这样做.如果是这样,它的存储范例是什么?
我的主要问题如下.考虑以下设计和数据(以T-SQL显示):
CREATE TABLE dbo.Tree
(
[Key] int NOT NULL,
ID int NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tree ADD CONSTRAINT
PK_Tree PRIMARY KEY CLUSTERED
(
[Key],
ID
) WITH (...) ON [PRIMARY]
INSERT INTO TREE ([Key], ID) VALUES (1, 1), (1, 2), (1, 3), (1, 4).
Run Code Online (Sandbox Code Playgroud)
由于这是一个以两列作为PK的btree,我更正确地说"[Key] = 1"只存储一次,而"ID = [1,2,3,4]"将是单个值btree,而每个sé都没有叶值,因为没有行列不属于PK?
如何在PostgreSQL中工作?
Jer*_*hka 14
TL; DR版本 - 无论DBMS实现如何,您的密钥值始终存储在磁盘上.
PostgreSQL将在磁盘上存储4行,每行插入一行.SQL Server还将在磁盘上存储4行.B树是查找结构,而不是页面级存储结构.
在底层磁盘级别,PostgreSQL使用无序磁盘结构来存储数据.这是因为由于MVCC事务语义,PostgreSQL可能在任何给定时间维护行的多个副本.每行都有一个xmin和xmax,详细说明了当前行的创建和销毁事务ID.autovacuum进程执行ghost记录清理操作.PostgreSQL中的索引指向堆表结构中的行.这组幻灯片详细介绍了该过程.特别是,您需要查看幻灯片29,了解b树查找的发生方式,以及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);
Run Code Online (Sandbox Code Playgroud)
一旦你看到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)
Run Code Online (Sandbox Code Playgroud)
这是SQL Server存储它时的实际行数据.您将在整个输出中看到Key = 1的多个副本,然后是ID信息.可以在此处找到这些命令的支持信息.
PostgreSQL与SQL Server之间差异的原因来自PostgreSQL的MVCC实现.由于我们可能在PostgreSQL中有一行的多个副本,因此在磁盘上保留数据的多个副本而不是修改支持索引结构更为理想.只要有可能,PostgreSQL只进行堆更新,并仅在基础表上发布更新.SQL Server执行相同的操作,只有在可以避免更新支持索引时才会更新聚簇索引(或堆).
| 归档时间: |
|
| 查看次数: |
2430 次 |
| 最近记录: |