【发布时间】: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,但无法理解。
【问题讨论】:
我在 CREATE TABLE 语句中有以下行:
field1_id bigint DEFAULT nextval('table1_field1_id_seq'::regclass) NOT NULL,
上面的regclass是什么意思?加::regclass是绝对必要的吗?
注意:我看过 Postgresql 文档 link,它讲述了 regclass,但无法理解。
【问题讨论】:
根据我对文档的理解,oid 按类型细分。 regclass 是表示关系的数据库对象(因此它们属于元数据表 pg_class)。
它表示序列和DEFAULT 表达式之间的依赖关系(例如,如果在 INSERT 查询中没有提供显式值,则生成默认值的过程),因此如果在序列,查询不会通过,除非它被级联(通过写DROP SEQUENCE table1_field1_id_seq CASCADE)。
【讨论】:
DROP SEQUENCE,我使用此序列作为DEFAULT 的列(字段)将删除该默认值?
regclass 会告诉引擎存在关系。
不,当调用像nextval 这样接受regclass 参数的函数时,您不需要转换为regclass,因为从text 到regclass 存在隐式转换。在某些其他情况下,可能需要显式转换为 regclass。
说明:
::regclass 是一个演员表,如::integer。
regclass 是一种“魔法”数据类型;它实际上是oid 或“对象标识符”的别名。请参阅文档中的Object identifier types。转换为regclass 是说“这是一个关系的名称,请将其转换为该关系的 oid”的快捷方式。转换为regclass 知道search_path,这与直接查询pg_class 的关系的oid 不同,因此转换为regclass 并不完全等同于子查询pg_class。
表是关系。序列和视图也是如此。因此,您也可以通过强制转换为 regclass 来获得视图或序列的 oid。
为text 到regclass 定义了隐式转换,因此如果您省略显式转换并且调用接受regclass 的函数,转换会自动完成。所以你确实不需要在nextval调用中需要它。
还有其他地方可以。例如,您不能直接将text 与oid 进行比较;所以你可以这样做:
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等
换句话说:
pg_class 中搜索与匹配名称的关系并将每个关系与其命名空间(架构)相关联search_path 中出现的顺序对剩余关系列表进行排序
【讨论】:
nextval(oid1),其中oid1 是table1_field1_id_seq 的oid。我说的对吗?
regclass 内部是一个oid,但它仍然显示为psql 输出中的表名等。如果要显示实际的oid,可以转换为oid,这就是'sequence_name'::regclass::oid 所做的;转换为regclass,然后将其转换为oid,因此不再格式化为显示。正如我所说,regclass 是一种神奇的类型。
select 1234::regclass,如果您想知道特定的 pg_toast_ 是什么表,这将很有用表关联。