PostgreSQL12开始引入了Generated columns,用来创建虚拟列。虚拟列是表达式,表达式中只能引用本表的非 generated column 字段,不可以引用其它表的字段,且必须使用immutable类型的表达式和操作符。
说明:
A generated column is a special column that is always computed from other columns. Thus, it is for columns what a view is for tables. There are two kinds of generated columns: stored and virtual. A stored generated column is computed when it is written (inserted or updated) and occupies storage as if it were a normal column. A virtual generated column occupies no storage and is computed when it is read. Thus, a virtual generated column is similar to a view and a stored generated column is similar to a materialized view (except that it is always updated automatically). PostgreSQL currently implements only stored generated columns.
语法:
GENERATED ALWAYS AS ( generation_expr ) STORED |
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |
例子:
v_c3列作为虚拟列。
bill=# create table t_virtual(c1 int,c2 int,v_c3 int GENERATED ALWAYS AS(c1 + c2) stored);
CREATE TABLE
无法向v_c3列进行插入:
bill=# insert into t_virtual values(1,2,3);
ERROR: cannot insert into column "v_c3"
DETAIL: Column "v_c3" is a generated column.
插入数据:
bill=# insert into t_virtual values(1,2);
INSERT 0 1
bill=# select * from t_virtual ;
c1 | c2 | v_c3
----+----+------
1 | 2 | 3
(1 row)
并且我们可以在虚拟列上创建索引:
bill=# create index idx_t_v on t_virtual (v_c3);
CREATE INDEX
可以正常使用索引查询:
bill=# explain select * from t_virtual where v_c3 = 1;
QUERY PLAN
--------------------------------------------------------------------------
Index Scan using idx_t_v on t_virtual (cost=0.28..2.89 rows=1 width=12)
Index Cond: (v_c3 = 1)
(2 rows)
总结:
- Generated columns支持两种类型:Stored (computed on write) 和 Virtual
(computed on read),目前仅支持 stored
类型,数据存储到磁盘上。stored有点类似物化视图,而virtual则是类似视图。 - Generated columns 字段只读,不支持 INSRET 和 UPDATE。
- Generated columns 只能引用本表的非 generated column 字段,不可以引用其它表的字段。
- Generated columns 使用的表达式和操作符必须是 Immutable 属性。
- Generated columns 支持创建索引。
参考链接:
https://www.postgresql.org/docs/12/ddl-generated-columns.html