暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL 18:虚拟生成列

刺史武都 2025-02-12
53

这是关于 PostgreSQL 18 的另一个功能:虚拟生成列。生成的列已经可用,但它们需要“存储”。这​​意味着表达式的结果存储到磁盘,并在写入时计算结果,但您无法明确写入该列。在查看虚拟生成列之前,让我们快速刷新一下“存储”的生成列。

考虑如下这样的简单表格:

postgres=# create table t ( a int, b int );
CREATE TABLE
postgres=# insert into t values (1,99);
INSERT 0 1
复制

如果您想自动计算“a”和“b”的总和,您可以使用生成的列:

postgres=# alter table t add column c int generated always as (a+b) stored; 
ALTER TABLE
postgres=# select * from t;
 a | b  |  c  
---+----+-----
 1 | 99 | 100
(1 row)
复制

如上所述,您不能直接写入该列:

postgres=# update t set c = -1 where a = 1;
ERROR:  column "c" can only be updated to DEFAULT
DETAIL:  Column "c" is a generated column.
复制

这种生成的列的缺点是,表达式的结果实际上存储到磁盘,显然会占用空间。

随着“虚拟生成列”的加入,这个概念在某种程度上被颠覆了:虚拟列的表达式是在读取时计算的,因此磁盘上没有存储。另一方面,你在读取时也要计算表达式,而不是像“存储”虚拟列那样在写入时计算:

postgres=# alter table t add column d int generated always as (a-b) virtual; 
ALTER TABLE
postgres=# select * from t;
 a | b  |  c  |  d  
---+----+-----+-----
 1 | 99 | 100 | -98
(1 row)
复制

从 PostgreSQL 18 开始默认为虚拟,这也反映在这里:

ostgres=# \d t
                               Table "public.t"
 Column |  Type   | Collation | Nullable |              Default              
--------+---------+-----------+----------+------------------------------------
 a      | integer |           |          | 
 b      | integer |           |          | 
 c      | integer |           |          | generated always as (a + b) stored
 d      | integer |           |          | generated always as (a - b)

复制

原文地址:https://www.dbi-services.com/blog/postgresql-18-virtual-generated-columns/
原文作者:Daniel Westermann

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论