PostgreSQL 18新特性之虚拟生成列

B站影视 日本电影 2025-03-20 08:51 3

摘要:为此,PostgreSQL 18 即将引入一个新的增强:虚拟生成列。这种类型的字段值不需要存储,而是在读取数据时进行计算。虚拟生成列类似于视图,而存储生成列更像物化视图。

PostgreSQL 12 提供了生成列(GENERATED ALWAYS AS STORED)功能,但是只能支持存储型的生成列,需要占用存储空间,更新成本高。

为此,PostgreSQL 18 即将引入一个新的增强:虚拟生成列。这种类型的字段值不需要存储,而是在读取数据时进行计算。虚拟生成列类似于视图,而存储生成列更像物化视图。

我们可以通过在CREATE TABLE或者ALTER TABLE语句中指定字段的GENERATED ALWAYS AS约束来创建一个生成列:

column_name data_type GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ]

其中,GENERATED ALWAYS AS表示创建生成列;generation_expr 指定了生成列的表达式;STORED表示存储生成列,VIRTUAL代表虚拟生成列(默认值)。

例如以下语句:

CREATE TABLE t_circle( id INTEGERPRIMARYKEY, x NUMERICNOTNULL, y NUMERICNOTNULL, radius NUMERICNOTNULL, perimeter NUMERIC GENERATED ALWAYS AS(2*3.14159265* radius) VIRTUAL);ALTERTABLE t_circle ADD area NUMERIC GENERATED ALWAYS AS(3.14159265* radius * radius) VIRTUAL;

首先,CREATE TABLE语句为表 t_circle 定义了一个生成列 perimeter,表示圆的周长。然后,使用ALTER TABLE语句增加一个生成列 area ,表示圆的面积。

接下来我们插入一些数据:

INSERT INTO t_circle VALUES(1,2,2,5);SELECT*FROM t_circle;id|x|y|radius|perimeter |area |--|-|-|------|||1|2|2| 5|31.41592650|78.53981625|INSERTINTO t_circle(id, x, y, radius ,perimeter)VALUES(2,0,0,1,6.28318530);SQL Error [42601]: ERROR: cannot insertintocolumn"perimeter" Detail: Column"perimeter"is a generated column.

第一个插入语句没有指定生成列的值,由数据库自动计算;第二个插入语句为 perimeter 提供了数据,执行失败;INSERT和UPDATE语句不能为生成列指定值。

虚拟生成列具有查询时实时计算,不占用存储空间等优点;但是目前 PostgreSQL 18 提供的虚拟生成列还存在一些限制:

不支持索引,包括唯一约束;不支持扩展统计信息;不支持外键约束;不支持非空约束(可以使用检查约束);不支持 ALTER TABLE / DROP EXPRESSION 语句;不支持域类型;不支持逻辑复制。

来源:散文随风想

相关推荐