受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

8.19. 对象标识符类型 #

对象标识符(OID)在 PostgreSQL 内部被用作 若干系统表的主键。类型 oid 表示一个对象标识符。 此外还有若干 oid 的别名类型,统称为 regsomethingTable 8.26 给出了概要说明。

oid 类型目前实现为无符号 4 字节整数。因此, 在大型数据库中,它不足以提供数据库范围内的唯一性,甚至在大型的 单个表中也无法保证唯一性。

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。

Table 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,具体取决于当前搜索路径。 regprocregoper 只接受唯一 (未重载)的输入名称,因此用途有限;多数情况下, regprocedureregoperator 更合适。 对于 regoperator,可以通过在未使用的操作数位置写入 NONE 来表示一元操作符。

这些类型的输入函数允许在各个标记之间插入空白,并且会把大写字母 折叠为小写,双引号内除外;这样做是为了让语法规则更接近 SQL 中 书写对象名的方式。反过来,如果需要让输出成为有效的 SQL 标识符, 输出函数会自动加上双引号。例如,一个名为 Foo (大写 F)且带两个整数参数的函数,其 OID 可以写成 ' "Foo" ( int, integer ) '::regprocedure。 输出则会是 "Foo"(integer,integer)。函数名和 参数类型名也都可以带模式限定。

许多内置的 PostgreSQL 函数接受表的 OID 或其他数据库对象的 OID。为了方便,这些函数会被声明为接受 regclass(或相应的 OID 别名类型)参数。这意味着你 不必手工查找对象的 OID,只需把对象名写成字符串字面值即可。例如, nextval(regclass) 函数接受一个序列关系的 OID, 因此可以这样调用:

nextval('foo')              作用于序列foo
nextval('FOO')              同上
nextval('"Foo"')            作用于序列Foo
nextval('myschema.foo')     作用于myschema.foo
nextval('"myschema".foo')   同上
nextval('foo')              在搜索路径中查找foo

Note

当你把这类函数的参数写成未经修饰的字符串字面值时,它会变成 regclass(或相应类型)的常量。由于这实际上只是 一个 OID,所以即便对象后来被重命名、重新分配到其他模式等,它 仍会持续指向最初识别到的对象。这种早绑定行为, 通常很适合列默认值和视图中的对象引用。但有时你可能希望得到 后绑定行为,也就是在运行时再解析对象引用。要实现 后绑定,请强制把该常量存储为 text 常量,而不是 regclass

nextval('foo'::text)      foo运行时被查找

to_regclass() 及其同类函数也可用于执行运行时 查找。参见 Table 9.74

regclass 的另一个实际用途,是查找 information_schema 视图中列出的表的 OID,而这些 视图本身并不直接提供此类 OID。例如,你可能想调用 pg_relation_size() 函数,而它需要表的 OID。 综合上述规则,正确的写法是:

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 值严格单调递增,并且在数据库集簇的生命周期内 不会被重用。

系统使用的第三种标识符类型是 cid,也就是命令标识符。 这是系统列 cmincmax 的数据类型。命令标识符同样是 32 位量。

系统使用的最后一种标识符类型是 tid,也就是元组标识符 (行标识符)。这是系统列 ctid 的数据 类型。一个元组 ID 是一对值(块号、块内元组索引),用来标识该行在 其所属表中的物理位置。

(系统列的更多说明见 Section 5.6。)

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。