OID
一个 OID
是 PostgreSQL 用作数据库对象唯一标识符(主键)的数据类型。 OID
数据类型实现为一个无符号 32 位整数。
历史用法
在 PostgreSQL 7.2 之前,OID
是强制性的,而在 PostgreSQL 8.1 之前,OID
默认包含在用户表中的行中。这提供了提供潜在唯一标识符以区分其他相同表行的边际优势,但是此唯一性无法保证,因为 OID
计数器可能会达到数据类型 32 位容量的上限并环绕。
在 PostgreSQL 8.1 和 PostgreSQL 11 之间的版本中,仍然可以为用户表启用 OID
,方法是在表定义中指定 WITH OIDS
,或设置 配置参数 default_with_oids
。
如果已启用,则在 psql
中执行 INSERT
后,将显示最近更新的 OID
并将其存储在变量 LASTOID
中。但是,除非表是使用 OID
明确创建的,否则此值通常为零。
postgres=# CREATE TABLE oidtest (id int) WITH OIDS; CREATE TABLE
postgres=# INSERT INTO oidtest VALUES(1); INSERT 10992082 1
postgres=# SELECT oid, id FROM oidtest; oid | id ----------+---- 10992082 | 1 (1 row)
从表中删除 OID
源自旧版 PostgreSQL 版本且默认启用 OID
的表可以使用 ALTER TABLE ... SET WITHOUT OIDS
删除这些 OID,但是请注意,与正常的列删除相比,这将需要完全重写表。
OID 和系统目录表
在 PostgreSQL 11 及更早版本中,系统目录表上的 OID
是特殊的“隐藏”列,需要显式选择,例如 SELECT oid, * FROM pg_class
。
PostgreSQL 12 中的 OID
从 PostgreSQL 12 开始,不再可以为用户表启用 OID
。此外,它们现在被视为系统表上的普通列,并且始终可见。
有关更多信息,请参阅提交 578b2297。
OID 的分配
OID
从 16384 开始由 PostgreSQL 自动分配(此值由 src/include/access/transam.h 中的常量 FirstNormalObjectId
定义)。
OID
低于 16384 保留用于系统使用。
目前,1-9999 之间的 OID 保留用于手动分配给系统目录条目;其中 8000-9999 保留用于开发目的(根据提交 09568ec3,超过 9000 的保留用于分支使用)。
10000-11999 之间的 OID 用于由 genbki.pl 自动生成的 object;12000 到 16383 之间的 OID 将用于在引导过程中创建的 object。
脚本 src/include/catalog/unused_oids 可用于显示可用的 OID,甚至提供使用建议,例如:
$ src/include/catalog/unused_oids 4 - 9 111 388 - 389 560 - 583 786 - 789 811 - 816 1137 ... 6122 - 8431 8434 - 8455 8457 - 8594 8597 - 9743 9745 - 9999 Patches should use a more-or-less consecutive range of OIDs. Best practice is to start with a random choice in the range 8000-9999. Suggested random unused OID: 9004 (740 consecutive OID(s) available starting here)
有关更多详细信息,请参阅文档部分 OID 分配。
OID 和文件节点
当检查 PostgreSQL 的磁盘文件结构时,乍一看,与表关联的文件名似乎对应于 pg_class
中表的 OID
。但是,情况并非总是如此:文件名由 文件节点 标识,在正常情况下,文件节点最初与 OID
相同(注意:根据 src/backend/access/transam/xlog.c 中的注释,在崩溃情况后存在一些极端情况,在这种情况下可能并非如此),但可以更改,例如在完全重写表后。
示例
某些 OID 在其自然环境中
postgres=# \d pg_trigger Table "pg_catalog.pg_trigger" Column | Type | Collation | Nullable | Default ----------------+--------------+-----------+----------+--------- oid | oid | | not null | tgrelid | oid | | not null | tgname | name | | not null | tgfoid | oid | | not null | tgtype | smallint | | not null | tgenabled | "char" | | not null | tgisinternal | boolean | | not null | tgconstrrelid | oid | | not null | tgconstrindid | oid | | not null | tgconstraint | oid | | not null | tgdeferrable | boolean | | not null | tginitdeferred | boolean | | not null | tgnargs | smallint | | not null | tgattr | int2vector | | not null | tgargs | bytea | | not null | tgqual | pg_node_tree | | | tgoldtable | name | | | tgnewtable | name | | | Indexes: "pg_trigger_oid_index" UNIQUE, btree (oid) "pg_trigger_tgrelid_tgname_index" UNIQUE, btree (tgrelid, tgname) "pg_trigger_tgconstraint_index" btree (tgconstraint)
注意:以上示例取自 PostgreSQL 12;在早期版本中,第一列 oid
将不可见。
有用链接
- OID 降级为普通列:回顾过去 - 2019 年博客文章