对象标识符(OID)在 PostgreSQL 内部用作各种系统表的primary key。类型 oid
代表一个对象标识符。此外,还有几种 oid
的别名类型,每种都命名为 reg
。 表 8.26 概览。something
类型 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.mytable
是 regclass
可接受的输入(如果存在这样的表)。该值可能输出为 myschema.mytable
,或仅输出 mytable
,具体取决于当前搜索路径。 regproc
和 regoper
别名类型仅接受唯一的输入名称(非重载),因此它们的用途有限;对于大多数用途,regprocedure
或 regoperator
更合适。对于 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 sequencefoo
nextval('FOO') same as above nextval('"Foo"') operates on sequenceFoo
nextval('myschema.foo') operates onmyschema.foo
nextval('"myschema".foo') same as above nextval('foo') searches search path forfoo
当您将此类函数的参数写为未加修饰的文字字符串时,它将成为 regclass
类型(或相应的类型)的常量。由于这实际上只是一个 OID,因此它会跟踪原始标识的对象,即使后来重命名、模式重新分配等。这种“早期绑定”行为通常对于列默认值和视图中的对象引用是可取的。但有时您可能想要“延迟绑定”,即在运行时解析对象引用。要获得延迟绑定行为,请强制将常量存储为 text
常量而不是 regclass
:
nextval('foo'::text) foo
is looked up at runtime
to_regclass()
函数及其同类函数也可用于执行运行时查找。请参阅 表 9.76。
另一个 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)标识符。这是系统列 xmin
和 xmax
的数据类型。事务标识符是 32 位数量。在某些上下文中,使用 64 位变体 xid8
。与 xid
值不同,xid8
值严格单调递增,并且在数据库集群的生命周期内不会被重用。有关更多详细信息,请参阅 第 67.1 节。
系统使用的第三种标识符类型是 cid
,即命令标识符。这是系统列 cmin
和 cmax
的数据类型。命令标识符也是 32 位数量。
系统使用的最后一种标识符类型是 tid
,即元组标识符(行标识符)。这是系统列 ctid
的数据类型。元组 ID 是一个对(块编号,块内元组索引),它标识了行在表内的物理位置。
(系统列在 第 5.6 节 中有更详细的解释。)
如果您在文档中看到任何不正确、与您在使用特定功能时的经验不符或需要进一步澄清的内容,请使用此表单报告文档问题。