# 5.3.生成的列
生成的列是一个特殊的列,它总是根据其他列进行计算。因此,对于列来说,它就像视图对于表一样。生成的列有两种:存储列和虚拟列。存储生成的列在写入(插入或更新)时进行计算,并像普通列一样占用存储空间。虚拟生成的列不占用存储空间,在读取时进行计算。因此,虚拟生成的列类似于视图,存储生成的列类似于物化视图(只是它总是自动更新)。PostgreSQL目前只实现存储的生成列。
要创建生成的列,请使用始终生成
条款创建表格
,例如:
CREATE TABLE people (
...,
height_cm numeric,
height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED
);
关键词存储
必须指定才能选择生成列的存储类型。看见创建表格更多细节。
生成的列不能直接写入。在里面插入
或使现代化
命令时,不能为生成的列指定值,但必须指定关键字违约
可以指定。
考虑具有默认列和生成列的列之间的差异。如果没有提供其他值,则在第一次插入行时对列默认值求值一次;只要行发生更改,生成的列就会更新,并且不能被重写。列默认值不能引用表中的其他列;世代表达式通常会这样做。例如,列默认值可以使用volatile函数随机的
或引用当前时间的函数;生成的列不允许这样做。
对生成的列和涉及生成列的表的定义有几个限制:
生成表达式只能使用不可变函数,不能使用子查询或以任何方式引用当前行以外的任何内容。
生成表达式不能引用另一个生成的列。
生成表达式不能引用系统列,除非
片状
.生成的列不能有列默认值或标识定义。
生成的列不能是分区键的一部分。
外部表可以生成列。看见创建外部表详细信息。
对于继承:
如果父列是生成的列,则子列也必须是使用相同表达式生成的列。在子列的定义中,去掉
生成
子句,因为它将从父级复制。在多重继承的情况下,如果一个父列是生成的列,那么所有父列都必须是生成的列,并且具有相同的表达式。
如果父列不是生成的列,则子列可以定义为生成的列,也可以定义为非生成的列。
其他注意事项适用于生成列的使用。
生成的列与它们的基础基列分开维护访问权限。因此,可以对其进行安排,以便特定角色可以从生成的列中读取,但不能从底层的基本列中读取。
从概念上讲,生成的列在
之前
触发器已经启动。因此,对之前
触发器将反映在生成的列中。但相反,它不允许访问中生成的列之前
触发器。