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