Postgresql的隐藏系统列
Postgresql的隐藏系统列
和oracle数据库一样,postgresql也有自身的一套隐藏的系统列。下面介绍如下:
1.oid
oid是object identifier的简写,其相关的参数设置default_with_oids设置一般默认是false,或者创建表时指定with (oids=false),其值长度32bit,实际的数据库系统应用中并不能完全保证其唯一性; www.zzzyk.com
2.tableoid
是表对象的一个唯一标识符,可以和pg_class中的oid联合起来查看
3.xmin
是插入的事务标识符,是用来标识不同事务下的一个版本控制。每一次更新该行都会改变这个值。可以和mvcc版本结合起来看
4.xmax
是删除更新的事务标识符,如果该值不为0,则说明该行数据当前还未提交或回滚。比如设置begin事务时可以明显看到该值的变化
5.cmin
插入事务的命令标识符,从0开始
6.cmax
删除事务的命令标识符,或者为0
7.ctid www.zzzyk.com
是每行数据在表中的一个物理位置标识符,和oracle的rowid类似,但有一点不同,当表被vacuum full或该行值被update时该值可能会改变。所以定义表值的唯一性最好还是自己创建一个序列值的主键列来标识比较合适。不过使用该值去查询时速度还是非常快的。
下面举例说明:
postgres=# create table test(id int,name varchar);
CREATE TABLE
postgres=# insert into test select generate_series(1,3),repeat('kenyon',2);
INSERT 0 3
postgres=# select cmin,cmax,xmin,xmax,ctid from test;
cmin | cmax | xmin | xmax | ctid
------+------+------+------+-------
0 | 0 | 1852 | 0 | (0,1)
0 | 0 | 1852 | 0 | (0,2)
0 | 0 | 1852 | 0 | (0,3)
(3 rows)
我们可以看到xmin值是一样的,表示是同一个事务
postgres=# begin;
BEGIN
postgres=# insert into test values (4,'a');
INSERT 0 1
postgres=# insert into test values (5,'aa');
INSERT 0 1
postgres=# insert into test values (6,'aa');
INSERT 0 1
postgres=# insert into test values (7,'aad');
INSERT 0 1
postgres=# commit;
COMMIT
postgres=# select cmin,cmax,xmin,xmax,ctid,* from test;
cmin | cmax | xmin | xmax | ctid | id | name
------+------+------+------+-------+----+--------------
0 | 0 | 1852 | 0 | (0,1) | 1 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,2) | 2 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,3) | 3 | kenyonkenyon
0 | 0 | 1853 | 0 | (0,4) | 4 | a
1 | 1 | 1853 | 0 | (0,5) | 5 | aa
2 | 2 | 1853 | 0 | (0,6) | 6 | aa
3 | 3 | 1853 | 0 | (0,7) | 7 | aad
这里我们可以看到cmin和cmax值有了变化
postgres=# begin; www.zzzyk.com
BEGIN
postgres=# update test set name = 'keke' where id = 7;
UPDATE 1
postgres=# update test set name = 'kekeke' where id = 6;
UPDATE 1
postgres=# update test set name = 'kenyon_test' where id = 5;
UPDATE 1
在另外一个会话中我们去查看xmax值
postgres=# select cmin,cmax,xmin,xmax,ctid,* from test;
cmin | cmax | xmin | xmax | ctid | id | name
------+------+------+------+-------+----+--------------
0 | 0 | 1852 | 0 | (0,1) | 1 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,2) | 2 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,3) | 3 | kenyonkenyon
0 | 0 | 1853 | 0 | (0,4) | 4 | a
2 | 2 | 1853 | 1854 | (0,5) | 5 | aa
1 | 1 | 1853 | 1854 | (0,6) | 6 | aa
0 | 0 | 1853 | 1854 | (0,7) | 7 | aad
(7 rows)
原会话中我们执行commit并查看
postgres=# commit;
COMMIT
postgres=# select cmin,cmax,xmin,xmax,ctid,* from test;
cmin | cmax | xmin | xmax | ctid | id | name
------+------+------+------+--------+----+--------------
0 | 0 | 1852 | 0 | (0,1) | 1 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,2) | 2 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,3) | 3 | kenyonkenyon
0 | 0 | 1853 | 0 | (0,4) | 4 | a
0 | 0 | 1854 | 0 | (0,8) | 7 | keke
1 | 1 | 1854 | 0 | (0,9) | 6 | kekeke
2 | 2 | 1854 | 0 | (0,10) | 5 | kenyon_test
(7 rows)
这时我们可以看到ctid也有了变化,在原来的基础上(0,7)往上累积,另外xmax因为事务被commit 的缘故也被置为0了。 再做下delete和insert的一个简单操作
postgres=# delete from test where id = 1; www.zzzyk.com
DELETE 1
postgres=# insert into test values (8,'jackson');
INSERT 0 1
postgres=# select cmin,cmax,xmin,xmax,ctid,* from test;
cmin | cmax | xmin | xmax | ctid | id | name
------+------+------+------+--------+----+--------------
0 | 0 | 1852 | 0 | (0,2) | 2 | kenyonkenyon
0 | 0 | 1852 | 0 | (0,3) | 3 | kenyonkenyon
0 | 0 | 1853 | 0 | (0,4) | 4 | a
0 | 0 | 1854 | 0 | (0,8) | 7 | keke
1 | 1 | 1854 | 0 | (0,9) | 6 | kekeke
2 | 2 | 1854 | 0 | (0,10) | 5 | kenyon_test
0 | 0 | 1856 | 0 | (0,11) | 8 | jackson
这时我们可以看到其实delete的事务ID(xmin)值是1855,insert的(xmin)值是1856,ctid往上累计
最后看一下tableoid和pg_class中oid的关系,(oid不说了,系统中一般设置为false)
postgres=# select tableoid,cmin,cmax,xmin,xmax,ctid,* from test;
tableoid | cmin | cmax | xmin | xmax | ctid | id | name
----------+------+------+------+------+--------+----+--------------
24601 | 0 | 0 | 1852 | 0 | (0,2) | 2 | kenyonkenyon
24601 | 0 | 0 | 1852 | 0 | (0,3) | 3 | kenyonkenyon
24601 | 0 | 0 | 1853 | 0 | (0,4) | 4 | a
24601 | 0 | 0 | 1854 | 0
- 更多SQLServer疑问解答:
- 配置MSSQL复制指定快照文件夹提示:不是有效的路径或文件名
- 详细解读varchar和Nvarchar区别
- SQL SERVER 2005 同步复制技术
- 进程未能大容量复制到表 解决方法
- MSSql实例教程:MSSql数据库同步
- SQLServer2000同步复制技术实现(分发和订阅)
- sqlserver
- SQLSERVER
- 测试 sqlserver 最大用户数连接
- 写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的
- sqlserver2008的安装问题。
- 为什么安装的SQL server 2008我的没有MSSQLSERVER协议啊?
- 怎样把exel表里的数据复制到sqlserver表里
- sqlserver数据库主键和外键问题
- sqlserver 中的左表连接查询和右表连接查询有啥不同?有什么用?