PostgreSQL是否支持计算/计算列,例如MS SQL Server?我在文档中找不到任何内容,但是由于许多其他DBMS都包含此功能,所以我认为我可能会丢失一些内容。
PostgreSQL是否支持计算/计算列,例如MS SQL Server?我在文档中找不到任何内容,但是由于许多其他DBMS都包含此功能,所以我认为我可能会丢失一些内容。
Answers:
最多不支持Postgres 11 生成的列 -这是SQL标准中定义的,并且由某些RDBMS(包括DB2,MySQL和Oracle)实现。也没有SQL Server 的类似“计算列”。
STORED
生成的列在Postgres 12中引入。琐碎的例子:
CREATE TABLE tbl (
int1 int
, int2 int
, product bigint GENERATED ALWAYS AS (int1 * int2) STORED
);
db <> 在这里拨弄
VIRTUAL
生成的列可能带有下一个迭代之一。(尚未在Postgres 13中)。
有关:
在那之前,你可以模拟VIRTUAL
生成具有列函数使用属性符号(tbl.col
),其外观和工作方式就像一个虚拟的生成列。出于历史原因,Postgres中存在某种语法上的奇怪之处,并且恰好适合这种情况。这个相关的答案有代码示例:
表达式(看起来像一列)未包含在中SELECT * FROM tbl
。您始终必须明确列出它。
也可以通过匹配的表达式索引来支持-提供的功能是IMMUTABLE
。喜欢:
CREATE FUNCTION col(tbl) ... AS ... -- your computed expression here
CREATE INDEX ON tbl(col(tbl));
或者,您可以使用来实现类似的功能,还可以VIEW
选择与表达式索引结合使用。然后SELECT *
可以包括生成的列。
STORED
可以使用功能相同的方式使用触发器来实现“ Persisted”()计算列。
物化视图是一个紧密相关的概念,自Postgres 9.3开始实施。
在早期版本中,可以手动管理MV。
是的你可以!! 该解决方案应该简单,安全且高效...
我是Postgresql的新手,但是看来您可以通过将expression index与视图配对使用来创建计算列(该视图是可选的,但会使生活变得更轻松)。
假设我的计算为md5(some_string_field)
,则将索引创建为:
CREATE INDEX some_string_field_md5_index ON some_table(MD5(some_string_field));
现在,任何作用于查询的查询MD5(some_string_field)
都将使用索引,而不是从头开始计算索引。例如:
SELECT MAX(some_field) FROM some_table GROUP BY MD5(some_string_field);
您可以使用explain进行检查。
但是,此时您依赖表的用户确切地知道如何构造该列。为了使生活更轻松,您可以VIEW
在原始表的增强版本上创建一个,将计算值添加为新列:
CREATE VIEW some_table_augmented AS
SELECT *, MD5(some_string_field) as some_string_field_md5 from some_table;
现在,所有使用的查询some_table_augmented
都可以使用,some_string_field_md5
而不必担心它的工作方式。它们只会获得良好的性能。该视图不会复制原始表中的任何数据,因此从内存角度和性能角度来说都是很好的选择。但是请注意,您不能只在源表中更新/插入视图,但是,如果您确实需要,我相信可以使用规则将插入和更新重定向到源表(在最后一点上我可能是错的,因为我从未亲自尝试过)。
编辑:看来,如果查询涉及竞争索引,则计划程序引擎有时可能根本不使用expression-index。该选择似乎取决于数据。
if the query involves competing indices
?
一种方法是使用触发器!
CREATE TABLE computed(
one SERIAL,
two INT NOT NULL
);
CREATE OR REPLACE FUNCTION computed_two_trg()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$
BEGIN
NEW.two = NEW.one * 2;
RETURN NEW;
END
$BODY$;
CREATE TRIGGER computed_500
BEFORE INSERT OR UPDATE
ON computed
FOR EACH ROW
EXECUTE PROCEDURE computed_two_trg();
在更新或插入行之前触发触发器。它更改了我们要计算NEW
记录的字段,然后返回该记录。
insert into computed values(1, 2); insert into computed values(4, 8); commit; select * from computed;
然后返回了:1 2和4 8
insert into computed(one) values(1); insert into computed(one) values(4); commit; select * from computed;
该two
列的值将自动计算!
PostgreSQL 12支持生成的列:
生成的列
PostgreSQL 12允许创建生成的列,并使用其他列的内容使用表达式来计算其值。此功能提供了存储的生成的列,这些列在插入和更新时计算并保存在磁盘上。仅当将列作为查询的一部分读取时才计算的虚拟生成列尚未实现。
生成的列是特殊列,始终从其他列计算得出。因此,表的视图就是列。
CREATE TABLE people (
...,
height_cm numeric,
height_in numeric GENERATED ALWAYS AS (height_cm * 2.54) STORED
);
我有一个有效的代码并使用“计算”一词,我不在PostgreSQL上运行,而在PADB上运行
这是它的用法
create table some_table as
select category,
txn_type,
indiv_id,
accum_trip_flag,
max(first_true_origin) as true_origin,
max(first_true_dest ) as true_destination,
max(id) as id,
count(id) as tkts_cnt,
(case when calculated tkts_cnt=1 then 1 else 0 end) as one_way
from some_rando_table
group by 1,2,3,4 ;
具有Check约束的轻量级解决方案:
CREATE TABLE example (
discriminator INTEGER DEFAULT 0 NOT NULL CHECK (discriminator = 0)
);
field as 1 persisted
。