PostgreSQL 是否仅支持 STORED 生成的列?
Does PostgreSQL only support STORED generated columns?
前言
我给出了一些来自 PHP 的例子,只是为了说明我的开发环境。问题不是关于 PHP,而是纯粹关于 PostgreSQL。
PostgreSQL documentation about generated column 指出:
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.
但是,它只显示了该页面示例中的 存储列 的示例,而不是虚拟的。它还说:
The keyword STORED must be specified to choose the stored kind of generated column. See CREATE TABLE for more details.
...它链接到 CREATE TABLE page。在该页面中,文档明确指出模式是 GENERATED ALWAYS AS (expression) STORED
.
GENERATED ALWAYS AS ( generation_expr ) STORED
This clause creates the column as a generated column. The column cannot be written to, and when read the result of the specified
expression will be returned.
The keyword STORED is required to signify that the column will be computed on write and will be stored on disk.
The generation expression can refer to other columns in the table, but not other generated columns. Any functions and operators used must be immutable. References to other tables are not allowed.
我实际上尝试在 Laravel (PHP) 中实现一个虚拟字段,这是我到目前为止在迁移中想到的:
DB::statement('ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL');
正如你在这条语句中看到的,在entries
table。我想即时计算 do_hint
以便:
- 其实我可以从数据库中查询出来。当然,我也可以在 PHP 上生成它,但我想查询,这就是我想使用虚拟列的要点。
- 我想依赖 PostgreSQL 的性能而不是 PHP。
并且考虑到 stored 列仅生成一次(插入行时),这不是我想要的行为。我想要一个虚拟专栏,以便我可以即时阅读。
我的代码出现语句错误。
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "VIRTUAL"
LINE 1: ...hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL
^ (SQL: ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL)
指向VIRTUAL
的部分是问题所在。所以我想"Maybe, virtual generated column is the default behavior."所以我删除它并再次尝试,但它再次失败,抱怨必须定义生成的列的类型:
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at end of input
LINE 1: ...tags OR hint_due_date OR hint_created_at OR hint_updated_at)
^ (SQL: ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at))
所以,我的问题在标题中:PostgreSQL 目前只支持存储的虚拟列吗?难道此时没有办法获取虚拟列?
我的意思是,当文档说 "There are two kinds of generated columns: stored and virtual." 时让我感到困惑。是 (i) 只是想在这里介绍 virtual 和 stored generated column 的概念,还是 (ii) 宣传它在 PostgreSQL 上的新功能12?我的意思是,如果没有办法创建 虚拟生成的列 ,他们可以添加一条警告说 "Virtual generated columns are not possible at this point. We only support stored ones yet.",但文档中的任何地方都没有这样的警告。我很困惑。
提前致谢。
环境
- PHP 7.4.5
- Laravel 7
- PostgreSQL 12.2
是的,目前 PostgreSQL 仅支持存储生成的列。
您可以使用视图来获得虚拟生成列的功能。
不支持虚拟生成列的documentation clearly states。
PostgreSQL currently implements only stored generated columns.
这只出现在您引用的文档部分之后的一句话。
前言
我给出了一些来自 PHP 的例子,只是为了说明我的开发环境。问题不是关于 PHP,而是纯粹关于 PostgreSQL。
PostgreSQL documentation about generated column 指出:
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.
但是,它只显示了该页面示例中的 存储列 的示例,而不是虚拟的。它还说:
The keyword STORED must be specified to choose the stored kind of generated column. See CREATE TABLE for more details.
...它链接到 CREATE TABLE page。在该页面中,文档明确指出模式是 GENERATED ALWAYS AS (expression) STORED
.
GENERATED ALWAYS AS ( generation_expr ) STORED
This clause creates the column as a generated column. The column cannot be written to, and when read the result of the specified expression will be returned.
The keyword STORED is required to signify that the column will be computed on write and will be stored on disk.
The generation expression can refer to other columns in the table, but not other generated columns. Any functions and operators used must be immutable. References to other tables are not allowed.
我实际上尝试在 Laravel (PHP) 中实现一个虚拟字段,这是我到目前为止在迁移中想到的:
DB::statement('ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL');
正如你在这条语句中看到的,在entries
table。我想即时计算 do_hint
以便:
- 其实我可以从数据库中查询出来。当然,我也可以在 PHP 上生成它,但我想查询,这就是我想使用虚拟列的要点。
- 我想依赖 PostgreSQL 的性能而不是 PHP。
并且考虑到 stored 列仅生成一次(插入行时),这不是我想要的行为。我想要一个虚拟专栏,以便我可以即时阅读。
我的代码出现语句错误。
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "VIRTUAL"
LINE 1: ...hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL
^ (SQL: ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL)
指向VIRTUAL
的部分是问题所在。所以我想"Maybe, virtual generated column is the default behavior."所以我删除它并再次尝试,但它再次失败,抱怨必须定义生成的列的类型:
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at end of input
LINE 1: ...tags OR hint_due_date OR hint_created_at OR hint_updated_at)
^ (SQL: ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at))
所以,我的问题在标题中:PostgreSQL 目前只支持存储的虚拟列吗?难道此时没有办法获取虚拟列?
我的意思是,当文档说 "There are two kinds of generated columns: stored and virtual." 时让我感到困惑。是 (i) 只是想在这里介绍 virtual 和 stored generated column 的概念,还是 (ii) 宣传它在 PostgreSQL 上的新功能12?我的意思是,如果没有办法创建 虚拟生成的列 ,他们可以添加一条警告说 "Virtual generated columns are not possible at this point. We only support stored ones yet.",但文档中的任何地方都没有这样的警告。我很困惑。
提前致谢。
环境
- PHP 7.4.5
- Laravel 7
- PostgreSQL 12.2
是的,目前 PostgreSQL 仅支持存储生成的列。
您可以使用视图来获得虚拟生成列的功能。
不支持虚拟生成列的documentation clearly states。
PostgreSQL currently implements only stored generated columns.
这只出现在您引用的文档部分之后的一句话。