生成列 ------ 生成列是一种特殊的列,它总是由其他列计算得出。 生成列对于普通列来说,就像视图对于表一样。 生成列有两种类型:存储型和虚拟型。存储型生成列在写入(插入或更新)时进行计算,并像普通列一样占用存储空间。 虚拟型生成列不占用存储空间,在读取时进行计算。 因此,虚拟型生成列类似于视图,存储型生成列类似于物化视图(不同之处在于它总是自动更新)。 OushuDB 目前仅实现了存储型生成列。 要创建一个生成列,请在“CREATE TABLE”中使用“GENERATED ALWAYS AS”子句,例如: :: CREATE TABLE people ( ..., height_cm numeric, height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED ); 必须指定关键字STORED才能选择生成列的存储类型。 生成列不能直接写入。在INSERT或UPDATE命令中,不能为生成列指定值,但可以指定关键字DEFAULT。 考虑具有默认值的列和生成列之间的差异。如果在首次插入行时未提供其他值,则列默认值仅评估一次; 生成列会在行发生更改时更新且不能被覆盖。列默认值可能无法引用表中的其他列; 生成表达式通常会这样做。列默认值可以使用易失性函数,例如random() 或引用当前时间的函数; 生成列不允许这样做。 涉及生成列和包含生成列的表的定义存在若干限制: * 生成表达式只能使用不可变函数,并且无论如何都不能使用子查询或引用除当前行之外的任何内容。 * 生成表达式不能引用另一个生成列。 * 除tableoid外,生成表达式不能引用系统列。 * 生成列不能具有列默认值或标识定义。 * 生成列不能作为分区键的一部分。 * 外键表可以有生成列。 * 对于继承: * 如果父列是生成列,则子列也必须是使用相同表达式的生成列。在子列的定义中,省略GENERATED子句,因为它将从父列复制。 * 在多重继承的情况下,如果一个父列是生成列,那么所有父列都必须是生成列,并且具有相同的表达式。 * 如果父列不是生成列,子列可以被定义为生成列或不是。 生成列使用的其他注意事项: * 生成列与其基础列的访问权限是分别维护的。因此,可以进行这样的安排:特定角色可以从生成列读取数据,但不能从基础列读取。 * 生成列在概念上是在BEFORE触发器运行之后更新的。因此,在BEFORE触发器中对基列所做的更改将反映在生成列中。但相反,在BEFORE触发器中不允许访问生成列。