这个问题在这里已经有答案了:
postgresql中的计算/计算/虚拟/派生列(7个答案)
11个月前关门了。
前言
为了说明我的开发环境,我给出了一些php示例。问题不在于php,而在于postgresql。
关于生成列的postgresql文档说明:
生成的列有两种:存储列和虚拟列。存储生成的列在写入(插入或更新)时进行计算,并像普通列一样占用存储空间。虚拟生成的列不占用存储空间,在读取时进行计算。
但是,它只在该页的示例中显示存储列的示例,而不是虚拟列。它还说:
必须指定关键字stored才能选择生成列的存储类型。有关详细信息,请参见创建表。
…它链接到创建表页的位置。在那一页中,文档清楚地指出了模式是 GENERATED ALWAYS AS (expression) STORED
.
始终生成为(generation\u expr)存储
此子句将列创建为生成的列。无法写入列,读取时将返回指定表达式的结果。
关键字stored表示列将在写入时计算并存储在磁盘上。
生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和运算符都必须是不可变的。不允许引用其他表。
实际上,我尝试在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');
正如你在这份声明中看到的,有 hint_hash
, hint_tags
以及其他几个布尔列(在 hint_*
全球模式) entries
table。我想计算一下 do_hint
以便:
我实际上可以从数据库中查询它。当然,我也可以在php上生成它,但是我想查询,这就是我想使用虚拟列的要点。
我想依靠postgresql的性能而不是php。
考虑到存储列只生成一次(插入行时),这不是我想要的行为。我想有一个虚拟的专栏,这样我就可以随时阅读。
我的代码中有语句错误。
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
部分原因是问题。所以我想“可能,虚拟生成的列是默认行为。”所以我删除了它并重试,但它再次失败,抱怨必须定义生成列的类型:
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是否只支持存储的虚拟列?此时是否无法获取虚拟列?
我的意思是,文档中说“有两种生成的列:存储列和虚拟列”,这让我很困惑。它(i)只是试图在这里引入虚拟和存储生成列的概念,还是(ii)宣传它在postgresql12上的新特性?我的意思是,如果没有办法创建虚拟生成的列,他们可以添加一个警告,说“此时不可能创建虚拟生成的列”。我们只支持存储的文件。”但是文档中没有这样的警告。我很困惑。
提前谢谢。
环境
php 7.4.5版
拉威尔7
postgresql 12.2版
2条答案
按热度按时间5cg8jx4n1#
文档明确指出不支持虚拟生成的列。
postgresql目前只实现存储的生成列。
这只出现在您引用的文档部分后面的一句话。
sauutmhj2#
是的,目前postgresql只支持存储生成的列。
您可以使用视图来获取虚拟生成列的功能。