Postgresql 中文操作指南

8.19. Object Identifier Types #

PostgreSQL 在内部将对象标识符 (OID) 用作各种系统表的主键。类型 oid 表示一个对象标识符。 oid 也有多个别名类型,每个都命名为 reg_something_Table 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。

Table 8.26. Object Identifier Types

Name

References

Description

Value Example

oid

any

numeric object identifier

564182

regclass

pg_class

relation name

pg_type

regcollation

pg_collation

collation name

"POSIX"

regconfig

pg_ts_config

text search configuration

english

regdictionary

pg_ts_dict

text search dictionary

simple

regnamespace

pg_namespace

namespace name

pg_catalog

regoper

pg_operator

operator name

+

regoperator

pg_operator

operator with argument types

*(integer,​integer) or -(NONE,​integer)

regproc

pg_proc

function name

sum

regprocedure

pg_proc

function with argument types

sum(int4)

regrole

pg_authid

role name

smithee

regtype

pg_type

data type name

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

Note

将此类函数的自变量写为朴素的文本文字时,它将成为 regclass 类型(或相应的类型)的常量。由于这只是一种 OID,因此它将跟踪最初标识的对象,而不受后续重命名、模式重新分配等的约束。此“早期绑定”行为通常对于列默认值和视图中的对象引用是理想的。但有时你可能需要“延迟绑定”,其中对象引用将在运行时进行解析。为了获得延迟绑定行为,强制将常量存储为 text 常量,而不是 regclass

nextval('foo'::text)      foo is looked up at runtime

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

使用 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 ...

not recommended,因为它对于搜索路径之外的表或需要引用符号的名称会失败。

大多数 OID 别名类型的附加属性是依赖关系的创建。如果这些类型之一的常量出现在存储表达式(比如列默认表达式或视图)中,它就会创建一个对所引用对象的依赖关系。比如,如果一个列有默认表达式 nextval('my_seq'::regclass),PostgreSQL 会理解默认表达式取决于序列 my_seq,这样系统就不会让序列被删除而不先删除默认表达式。nextval('my_seq'::text) 的替代创建了一个依赖关系。(regrole 是该属性的例外。这种类型的常量不在存储表达式中允许使用。)

系统使用的另一个标识符类型是 xid,即事务(缩写为 xact)标识符。这是系统列 xminxmax 的数据类型。事务标识符是 32 位量。在某些情况下,使用 64 位变体 xid8。与 xid 值不同,xid8 值严格单调增加,并且不能在数据库集群的生命周期内重复使用。有关详细信息,请参阅 Section 74.1

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

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

(系统列在 Section 5.5 中得到了进一步解释。)