对象标识符(OID)在 PostgreSQL 内部用作各种系统表的主键。类型 oid
表示一个对象标识符。还有几个 oid
的别名类型,每个都命名为 reg
。表 8.26 展示了一个概述。something
oid
类型目前被实现为一个无符号四字节整数。因此,它不足以在大型数据库中,甚至在大型的单个表中提供数据库范围的唯一性。
oid
类型本身除了比较之外几乎没有操作。但是,它可以转换为整数,然后使用标准整数运算符进行操作。(如果这样做,请注意可能出现的有符号与无符号的混淆。)
OID 别名类型除了专门的输入和输出例程外,没有自己的操作。这些例程能够接受和显示系统对象的符号名称,而不是类型 oid
将使用的原始数值。别名类型允许简化查找对象的 OID 值。例如,要检查与表 mytable
相关的 pg_attribute
行,可以编写
SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;
而不是
SELECT * FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');
虽然这本身看起来还不错,但它仍然过于简化。如果不同模式中有多个名为 mytable
的表,则需要更复杂的一个子选择来选择正确的 OID。regclass
输入转换器根据模式路径设置处理表查找,因此它会自动执行“正确的事情”。类似地,将表的 OID 转换为 regclass
对于符号显示数值 OID 很方便。
表 8.26. 对象标识符类型
名称 | 引用 | 描述 | 值示例 |
---|---|---|---|
oid |
任意 | 数值对象标识符 | 564182 |
regclass |
pg_class |
关系名称 | pg_type |
regcollation |
pg_collation |
排序规则名称 | "POSIX" |
regconfig |
pg_ts_config |
文本搜索配置 | english |
regdictionary |
pg_ts_dict |
文本搜索字典 | simple |
regnamespace |
pg_namespace |
命名空间名称 | pg_catalog |
regoper |
pg_operator |
运算符名称 | + |
regoperator |
pg_operator |
带有参数类型的运算符 | *(integer,integer) 或 -(NONE,integer) |
regproc |
pg_proc |
函数名称 | sum |
regprocedure |
pg_proc |
带有参数类型的函数 | sum(int4) |
regrole |
pg_authid |
角色名称 | smithee |
regtype |
pg_type |
数据类型名称 | integer |
按命名空间分组的对象的 OID 别名类型都接受模式限定的名称,并且如果该对象在没有限定的情况下在当前搜索路径中找不到,则会在输出时显示模式限定的名称。例如,myschema.mytable
是 regclass
的可接受输入(如果存在这样的表)。该值可能会输出为 myschema.mytable
,或者仅仅是 mytable
,具体取决于当前的搜索路径。regproc
和 regoper
别名类型只会接受唯一的(未重载的)输入名称,因此它们的使用有限;对于大多数用途,regprocedure
或 regoperator
更合适。对于 regoperator
,一元运算符通过为未使用的操作数编写 NONE
来标识。
这些类型的输入函数允许标记之间有空格,并将大写字母折叠为小写字母,除非在双引号内;这样做是为了使语法规则类似于 SQL 中书写对象名称的方式。相反,输出函数将在需要时使用双引号,以使输出成为有效的 SQL 标识符。例如,一个名为 Foo
(大写 F
)的函数,带有两个整数参数的 OID 可以输入为 ' "Foo" ( int, integer ) '::regprocedure
。输出将看起来像 "Foo"(integer,integer)
。函数名和参数类型名也都可以用模式限定。
许多内置的 PostgreSQL 函数接受表的 OID 或其他类型的数据库对象,为了方便起见,声明为接受 regclass
(或相应的 OID 别名类型)。这意味着您不必手动查找对象的 OID,而只需将其名称作为字符串文字输入即可。例如,nextval(regclass)
函数接受序列关系的 OID,因此您可以这样调用它
nextval('foo') operates on sequencefoo
nextval('FOO') same as above nextval('"Foo"') operates on sequenceFoo
nextval('myschema.foo') operates onmyschema.foo
nextval('"myschema".foo') same as above nextval('foo') searches search path forfoo
当您将此类函数的参数写为未修饰的文字字符串时,它将成为 regclass
(或相应类型)的常量。由于这实际上只是一个 OID,因此即使稍后重命名、重新分配模式等,它也会跟踪最初标识的对象。这种“早期绑定”行为对于列默认值和视图中的对象引用通常是可取的。但有时您可能希望“后期绑定”,其中对象引用在运行时解析。要获得后期绑定行为,请强制将常量存储为 text
常量而不是 regclass
nextval('foo'::text) foo
is looked up at runtime
to_regclass()
函数及其同类函数也可用于执行运行时查找。请参阅表 9.74。
使用 regclass
的另一个实际示例是查找 information_schema
视图中列出的表的 OID,这些视图不直接提供此类 OID。例如,可能希望调用需要表 OID 的 pg_relation_size()
函数。考虑到上述规则,正确的方法是
SELECT table_schema, table_name, pg_relation_size((quote_ident(table_schema) || '.' || quote_ident(table_name))::regclass) FROM information_schema.tables WHERE ...
quote_ident()
函数将处理在需要时对标识符加双引号。看似更简单的
SELECT pg_relation_size(table_name) FROM information_schema.tables WHERE ...
是不推荐的,因为它对于不在您的搜索路径中或具有需要引号的名称的表将失败。
大多数 OID 别名类型的一个附加属性是创建依赖关系。如果这些类型之一的常量出现在存储的表达式中(例如列默认表达式或视图),它将创建对所引用对象的依赖关系。例如,如果一个列有一个默认表达式 nextval('my_seq'::regclass)
,PostgreSQL 知道默认表达式依赖于序列 my_seq
,因此系统不会允许在不首先删除默认表达式的情况下删除该序列。nextval('my_seq'::text)
的替代方法不会创建依赖关系。(regrole
是此属性的例外。此类型的常量不允许出现在存储的表达式中。)
系统使用的另一个标识符类型是 xid
,或事务(缩写为 xact)标识符。这是系统列 xmin
和 xmax
的数据类型。事务标识符是 32 位的值。在某些上下文中,使用 64 位变体 xid8
。与 xid
值不同,xid8
值严格单调增加,并且在数据库集群的生命周期内不能重用。有关更多详细信息,请参阅第 66.1 节。
系统使用的第三个标识符类型是 cid
,或命令标识符。这是系统列 cmin
和 cmax
的数据类型。命令标识符也是 32 位的值。
系统使用的最后一个标识符类型是 tid
,或元组标识符(行标识符)。这是系统列 ctid
的数据类型。元组 ID 是一对(块号,块内的元组索引),用于标识行在其表中的物理位置。
(系统列在第 5.6 节中进一步解释。)
如果您在文档中发现任何不正确、与您的特定功能体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。