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

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.mytablemytable,具体取决于当前搜索路径。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。例如,您可能希望调用 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 值严格单调地增加,且不能在数据库集簇的生存期内重复使用。有关详细信息,请参见第 66.1 节

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

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

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