regclass 在 Postgresql 中是啥意思

Posted

技术标签:

【中文标题】regclass 在 Postgresql 中是啥意思【英文标题】:What does regclass mean in Postgresqlregclass 在 Postgresql 中是什么意思 【发布时间】:2012-10-28 15:40:54 【问题描述】:

我在 CREATE TABLE 语句中有以下行:

field1_id bigint DEFAULT nextval('table1_field1_id_seq'::regclass) NOT NULL,

上面的regclass是什么意思?加::regclass是绝对必要的吗?

注意:我看过 Postgresql 文档 link,它讲述了 regclass,但无法理解。

【问题讨论】:

【参考方案1】:

根据我对文档的理解,oid 按类型细分。 regclass 是表示关系的数据库对象(因此它们属于元数据表 pg_class)。

它表示序列和DEFAULT 表达式之间的依赖关系(例如,如果在 INSERT 查询中没有提供显式值,则生成默认值的过程),因此如果在序列,查询不会通过,除非它被级联(通过写DROP SEQUENCE table1_field1_id_seq CASCADE)。

【讨论】:

那么,如果我级联DROP SEQUENCE,我使用此序列作为DEFAULT 的列(字段)将删除该默认值? 我想是的。这是我从文档中了解到的,但我没有测试它。 我认为强制转换为那种类型的 oid 会强制表达式和序列之间的依赖关系,因此从定义中删除它会删除 de 依赖关系,并让您在没有级联的情况下删除序列,但你应该再次测试以确认。 @Craig Ringer 说当类型不显式时,类型转换在查询执行时解析,然后推断关系 from 默认表达式 序列,但我认为引擎不会动态检查表达式是否与序列相关(关系序列另一个对象) ,并且拥有 regclass 会告诉引擎存在关系。【参考方案2】:

不,当调用像nextval 这样接受regclass 参数的函数时,您不需要转换为regclass,因为从textregclass 存在隐式转换。在某些其他情况下,可能需要显式转换为 regclass

说明:

::regclass 是一个演员表,如::integer

regclass 是一种“魔法”数据类型;它实际上是oid 或“对象标识符”的别名。请参阅文档中的Object identifier types。转换为regclass 是说“这是一个关系的名称,请将其转换为该关系的 oid”的快捷方式。转换为regclass 知道search_path,这与直接查询pg_class 的关系的oid 不同,因此转换为regclass 并不完全等同于子查询pg_class

表是关系。序列和视图也是如此。因此,您也可以通过强制转换为 regclass 来获得视图或序列的 oid。

textregclass 定义了隐式转换,因此如果您省略显式转换并且调用接受regclass 的函数,转换会自动完成。所以你确实不需要nextval调用中需要它。

还有其他地方可以。例如,您不能直接将textoid 进行比较;所以你可以这样做:

regress=> select * from pg_class where oid = 'table1'::regclass;

但不是这个:

regress=> select * from pg_class where oid = 'table1';
ERROR:  invalid input syntax for type oid: "table1"
LINE 1: select * from pg_class where oid = 'table1';

只是为了好玩,我尝试编写一个查询来执行转换为regclass 的等效操作。不要使用它,它主要是为了好玩,并试图演示实际发生的事情。除非你真的对 Pg 的工作原理感兴趣,否则你可以停止阅读这里。

据我了解,'sequence_name'::regclass::oid 大致相当于以下查询:

WITH sp(sp_ord, sp_schema) AS (
  SELECT 
    generate_series(1, array_length(current_schemas('t'),1)),
    unnest(current_schemas('t'))
)
SELECT c.oid
FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid)
INNER JOIN sp ON (n.nspname = sp.sp_schema)
WHERE c.relname = 'sequence_name'
ORDER BY sp.sp_ord
LIMIT 1;

除了它更短且更快。 current_schemas(...)的定义见System information functions等

换句话说:

获取一个 ab 数组,列出我们可以访问的所有模式,并将每个条目与其在数组中的位置的序数配对 在pg_class 中搜索与匹配名称的关系并将每个关系与其命名空间(架构)相关联 按照架构在search_path 中出现的顺序对剩余关系列表进行排序 并选择第一个匹配项

【讨论】:

所以我的查询行本质上会被解释为nextval(oid1),其中oid1table1_field1_id_seqoid。我说的对吗? @saji89 正确,但请注意,转换为 oid 是在执行查询时解决的,而不是在定义表时解决的。这很重要,因为如果您要删除并重新创建序列,它将有一个新的 oid,但名称相同。转换为 oid 将找到新的 oid。 所以即使我删除了一个序列,该序列的 oid 仍然存在于系统中? @saji89 抱歉,应该解释一下。虽然regclass 内部是一个oid,但它仍然显示psql 输出中的表名等。如果要显示实际的oid,可以转换为oid,这就是'sequence_name'::regclass::oid 所做的;转换为regclass,然后将其转换为oid,因此不再格式化为显示。正如我所说,regclass 是一种神奇的类型。 作为奖励,您还可以将 from 转换为数字 oid,即 select 1234::regclass,如果您想知道特定的 pg_toast_ 是什么表,这将很有用表关联。

以上是关于regclass 在 Postgresql 中是啥意思的主要内容,如果未能解决你的问题,请参考以下文章

postgresql 自增主键

从 postgresql 字段中删除自动增量

postgresql修改自增序列

PostgreSQL Partition

如何确定给定时区中的给定时间是不是在postgresql中是DST?

在 PostgreSQL 9.4.1 的切换和切回中是强制参数recover_target_timeline='latest'吗?