PostgreSQL的CTID

来源:这里教程网 时间:2026-03-14 20:56:02 作者:

PostgreSQL的CTID和Oracle的ROWID 类似. CTID字段存在于PostgresSQL表中,它对于表中的每条记录始终是唯一的。 它表示数据的物理位置。 我们来创建一个简单的表来验证一下上述概念.

dump=# CREATE TABLE events(id SERIAL);
CREATE TABLE
dump=# INSERT INTO events SELECT generate_series(1,10);
INSERT 0 10
dump=# select ctid,* from events;
 (0,1)  |  1
 (0,2)  |  2
 (0,3)  |  3
 (0,4)  |  4
 (0,5)  |  5
 (0,6)  |  6
 (0,7)  |  7
 (0,8)  |  8
 (0,9)  |  9
 (0,10) | 10

这里的CTID第一个值(0,1),第一个0代表页码,第二个1代表行号。

dump=# delete from events where id=1;
DELETE 1
dump=# select ctid,* from events ;
 (0,2)  |  2
 (0,3)  |  3
 (0,4)  |  4
 (0,5)  |  5
 (0,6)  |  6
 (0,7)  |  7
 (0,8)  |  8
 (0,9)  |  9
 (0,10) | 10
dump=# insert into events values(1);
INSERT 0 1
dump=# select ctid,* from events ;
 (0,2)  |  2
 (0,3)  |  3
 (0,4)  |  4
 (0,5)  |  5
 (0,6)  |  6
 (0,7)  |  7
 (0,8)  |  8
 (0,9)  |  9
 (0,10) | 10
 (0,11) |  1

删除了以后,重新insert被删除的行,会发现此行放在0页的最后一行

dump=# update events set id=12 where id=2;
UPDATE 1
dump=# select ctid,* from events ;
 (0,3)  |  3
 (0,4)  |  4
 (0,5)  |  5
 (0,6)  |  6
 (0,7)  |  7
 (0,8)  |  8
 (0,9)  |  9
 (0,10) | 10
 (0,11) |  1
 (0,12) | 12

更新了以后,会发现被更新的行放在0页的最后一行

dump=# vacuum events;
VACUUM
dump=# select ctid,* from events ;
 (0,3)  |  3
 (0,4)  |  4
 (0,5)  |  5
 (0,6)  |  6
 (0,7)  |  7
 (0,8)  |  8
 (0,9)  |  9
 (0,10) | 10
 (0,11) |  1
 (0,12) | 12

vacuum操作并不改变ctid值

dump=# vacuum full events;
VACUUM
dump=# select ctid,* from events ;
 (0,1)  |  3
 (0,2)  |  4
 (0,3)  |  5
 (0,4)  |  6
 (0,5)  |  7
 (0,6)  |  8
 (0,7)  |  9
 (0,8)  | 10
 (0,9)  |  1
 (0,10) | 12
dump=#

vacuum full操作使得数据被重新分布,ctid的值被reset

相关推荐