Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

8.19 对象标识符类型 #

PostgreSQL 内部将对象标识符 (OID) 用作各种系统表的唯一键。类型 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 any 数字对象标识符 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.72

使用 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 值严格单调递增,并且在数据库集群的生命周期内不能重复使用。有关更多详细信息,请参见 第 74.1 节

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

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

(系统列在 第 5.5 节 中进一步说明。)