支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3

8.19. 对象标识符类型 #

对象标识符(OID)在 PostgreSQL 内部用作各种系统表的主键。类型 oid 表示一个对象标识符。还有几个 oid 的别名类型,每个都命名为 regsomething表 8.26 展示了一个概述。

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.mytableregclass 的可接受输入(如果存在这样的表)。该值可能会输出为 myschema.mytable,或者仅仅是 mytable,具体取决于当前的搜索路径。regprocregoper 别名类型只会接受唯一的(未重载的)输入名称,因此它们的使用有限;对于大多数用途,regprocedureregoperator 更合适。对于 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 sequence foo
nextval('FOO')              same as above
nextval('"Foo"')            operates on sequence Foo
nextval('myschema.foo')     operates on myschema.foo
nextval('"myschema".foo')   same as above
nextval('foo')              searches search path for foo

注意

当您将此类函数的参数写为未修饰的文字字符串时,它将成为 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)标识符。这是系统列 xminxmax 的数据类型。事务标识符是 32 位的值。在某些上下文中,使用 64 位变体 xid8。与 xid 值不同,xid8 值严格单调增加,并且在数据库集群的生命周期内不能重用。有关更多详细信息,请参阅第 66.1 节

系统使用的第三个标识符类型是 cid,或命令标识符。这是系统列 cmincmax 的数据类型。命令标识符也是 32 位的值。

系统使用的最后一个标识符类型是 tid,或元组标识符(行标识符)。这是系统列 ctid 的数据类型。元组 ID 是一对(块号,块内的元组索引),用于标识行在其表中的物理位置。

(系统列在第 5.6 节中进一步解释。)

提交更正

如果您在文档中发现任何不正确、与您的特定功能体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。