PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 5. 数据定义 | 下一页

# 5.4. 系统字段

每个表都有几个系统字段，这些字段是由系统隐含定义的。因此， 这些名字不能用于用户定义的字段名。请注意这些限制与这个名字是否关键字无关， 把名字用引号括起来并不能让你逃离这些限制。你实际上不需要注意这些字段； 只要知道它们存在就可以了。

`oid`

  行对象标识符(对象ID)。这个字段只有在创建表的时候使用了`WITH OIDS` 或者是配置参数default_with_oids的值为真时出现。 这个字段的类型是`oid`(和字段同名)；参阅第 8.18 节获取有关这种类型的更多信息。

`tableoid`

  包含本行的表的OID。这个字段对那些从继承层次中选取的查询特别有用(参阅第 5.8 节)， 因为如果没有它的话，我们就很难说明一行来自哪个独立的表。`tableoid` 可以和`pg_class`的`oid`字段连接起来获取表名字。

`xmin`

  插入该行版本的事务标识(事务ID)。注意：在这个环境里，一个行版本是一行的一个状态； 一行的每次更新都为同一个逻辑行创建一个新的行版本。

`cmin`

  在插入事务内部的命令标识(从零开始)。

`xmax`

  删除事务的标识(事务ID)，如果不是被删除的行版本，那么是零。在一个可见行版本里， 这个字段有可能是非零。这通常意味着删除事务还没有提交，或者是一个删除的企图被回滚掉了。

`cmax`

  删除事务内部的命令标识符，或者是零。

`ctid`

  一个行版本在它所处的表内的物理位置。请注意，尽管`ctid` 可以用于非常快速地定位行版本，但每次`VACUUM FULL`之后， 一个行的`ctid`都会被更新或者移动。因此`ctid` 是不能作为长期的行标识符的。应该使用 OID ，或者更好是用户定义的序列号，来标识一个逻辑行。

OID是32位的量，是在同一个集群内通用的计数器上赋值的。 对于一个大型或者长时间使用的数据库，这个计数器是有可能重叠的。因此， 假定OID唯一是非常错误的，除非你自己采取了措施来保证它们是唯一的。 如果你需要标识表中的行，我们强烈建议使用序列号生成器。不过，也可以使用OID， 只要采取几个注意事项即可：

- 在使用OID标识行的每个表的OID字段创建一个唯一约束。在唯一约束(或者唯一索引)存在的时候， 系统会注意不去生成一个和现有行相同的OID。当然，只有在表中的数据行少于232 (40亿)行的时候才是可能的，而实际上表中的行最好远比这个小，要不性能就会受影响了。

- 绝对不要假设OIDs是跨表唯一的；如果你需要全数据库范围内的标识， 请使用`tableoid`和行的OID的组合。

- 需要OID的表应该带着`WITH OIDS`创建。从PostgreSQL 8.1开始，`WITHOUT OIDS`是缺省的。

事务标识符也是32位的量。在长时间运转的数据库里，它也可能会重叠。 只要我们采取一些合适的维护步骤，这并不是很要命的问题；参阅第 23 章 获取细节。不过，在长时间运行的环境里(超过十亿次事务)依赖事务ID的唯一性并非明智的做法。

命令标识符也是32位的量。这样就在一个事务里有232(四十亿)条SQL命令的硬限制。 在现实里这个限制应该不是什么问题，需要注意的是这个限制是SQL命令的条数， 而不是处理的行版本的条数。而且，只有真正修改数据库内容的命令才会消耗一个命令标识符。

上一页 | 起始页 | 下一页
约束 | 上一级 | 修改表