52

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

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

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

注意:我看过 Postgresql 文档链接,其中讲述了regclass,但无法理解。

4

2 回答 2

76

regclass不,在调用nextval接受参数的函数时不需要强制转换,因为从toregclass有一个隐式强制转换。在某些其他情况下,可能需要显式转换为。textregclassregclass

解释:

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

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

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

text为to定义了隐式转换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(...)

换句话说:

  • 获取一个 ab 数组,列出我们可以访问的所有模式,并将每个条目与一个序数配对,以表示其在数组中的位置
  • 搜索pg_class具有匹配名称的关系并将每个关系与其命名空间(模式)相关联
  • 按模式出现的顺序对剩余关系列表进行排序search_path
  • 并选择第一场比赛
于 2012-11-08T13:38:07.213 回答
0

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

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

于 2012-11-08T12:37:33.627 回答