## 8.19.对象标识符类型 [](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>) PostgreSQL在内部使用对象标识符(OID)作为各种系统表的主键。类型`老年人`表示对象标识符。也有几种别名类型`老年人`,每名`注册*`某物`*`.[表8.26](datatype-oid.html#DATATYPE-OID-TABLE)显示了一个概述。 这个`老年人`类型当前实现为无符号四字节整数。因此,它不足以在大型数据库中,甚至在大型单个表中提供数据库范围的唯一性。 这个`老年人`类型本身几乎没有无法比较的操作。但是,可以将其转换为整数,然后使用标准整数运算符对其进行操作。(如果这样做,请注意可能出现的有符号与无符号混淆。) OID别名类型除了专用的输入和输出例程之外,没有自己的操作。这些例程能够接受并显示系统对象的符号名,而不是输入的原始数值`老年人`会用的。别名类型允许简化对象OID值的查找。例如,检查`pg_属性`与表相关的行`空白表`可以这样写: ``` SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass; ``` 而不是: ``` SELECT * FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable'); ``` 虽然这看起来并没有那么糟糕,但它仍然过于简单化了。如果有多个名为`空白表`在不同的模式中。这个`regclass`输入转换器根据模式路径设置处理表查找,因此它会自动执行“正确的操作”。同样地,将表的OID转换为`regclass`用于数字OID的符号显示。 **表8.26.对象标识符类型** | 名称 | 工具书类 | 描述 | 价值榜样 | | --- | ---- | --- | ---- | | `老年人` | 任何 | 数字对象标识符 | `564182` | | `regclass` | `pg_类` | 关系名 | `pg_型` | | `规则整理` | `pg_校勘` | 排序规则名称 | `“POSIX”` | | `regconfig` | `pg_ts_配置` | 文本搜索配置 | `英语` | | `regdictionary` | `pg_t_dict` | 文本搜索词典 | `易于理解的` | | `regnamespace` | `pg_名称空间` | 命名空间名称 | `pg_目录` | | `雷戈` | `pg_操作员` | 操作员姓名 | `+` | | `regoperator` | `pg_操作员` | 具有参数类型的运算符 | `*(整数,​整数)`或`-(没有,​整数)` | | `regproc` | `pg_程序` | 函数名 | `总和` | | `注册程序` | `pg_程序` | 具有参数类型的函数 | `总和(整数4)` | | `后悔` | `pg_authid` | 角色名 | `史密西` | | `正则类型` | `pg_型` | 数据类型名称 | `整数` | 按命名空间分组的对象的所有OID别名类型都接受架构限定名称,如果在当前搜索路径中找不到未经限定的对象,则会在输出时显示架构限定名称。例如`myschema。空白表`是可接受的输入`regclass`(如果有这样一张桌子的话)。该值可以输出为`myschema。空白表`,或只是`空白表`,具体取决于当前搜索路径。这个`regproc`和`雷戈`别名类型只接受唯一的输入名称(不重载),因此它们的用途有限;大多数用途`注册程序`或`regoperator`更合适。对于`regoperator`,一元运算符通过书写进行标识`没有一个`对于未使用的操作数。 这些类型的输入函数允许标记之间使用空格,并将大写字母折叠成小写字母,双引号除外;这样做是为了使语法规则类似于在SQL中编写对象名的方式。相反,如果需要使输出成为有效的SQL标识符,输出函数将使用双引号。例如,名为`福`(大写)`F`)取两个整数参数可以输入为`““Foo”(int,integer)::regprocedure`.输出结果会是`“Foo”(整数,整数)`。函数名和参数类型名也可以是架构限定的。 许多内置的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,它将跟踪最初标识的对象,尽管以后会重命名、模式重新分配等。这种“早期绑定”行为通常适用于列默认值和视图中的对象引用。但有时您可能需要“后期绑定”,即在运行时解析对象引用。要获得后期绑定行为,请强制将常量存储为`文本`常数而不是`regclass`: ``` nextval('foo'::text) foo is looked up at runtime ``` 这个`to_regclass()`函数及其同级函数也可用于执行运行时查找。看见[表9.70](functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE). 另一个使用`regclass`查找列表中列出的表的OID`信息模式`视图,这些视图不直接提供此类OID。例如,有人可能希望打电话给`pg_关系_大小()`函数,它需要表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理解默认表达式取决于序列`我的`,因此系统不会在不删除默认表达式的情况下删除序列。选择`nextval('my_seq':text)`不会创建依赖项。(`后悔`这是一个例外。存储表达式中不允许使用此类型的常量。) 系统使用的另一种标识符类型是`希德`,或事务(缩写为xact)标识符。这是系统列的数据类型`xmin`和`最大值`.事务标识符是32位的量。在某些情况下,64位变体`xid8`被使用了。不像`希德`价值观`xid8`值严格地单调增加,并且不能在数据库集群的生存期内重用。 系统使用的第三种标识符类型是`cid`,或命令标识符。这是系统列的数据类型`cmin`和`cmax`.命令标识符也是32位的量。 系统使用的最终标识符类型为`tid`,或元组标识符(行标识符)。这是系统列的数据类型`ctid`.元组ID是一对(块编号、块内的元组索引),用于标识行在其表中的物理位置。 (系统列将在中进一步解释。)[第5.5节](ddl-system-columns.html).)