为了账号安全,请及时绑定邮箱和手机立即绑定

请问PostgreSQL中的计算/虚拟/派生列

/ 猿问

请问PostgreSQL中的计算/虚拟/派生列

慕桂英546537 2019-10-22 17:12:55

PostgreSQL中的计算/虚拟/派生列

PostgreSQL是否支持计算/计算列,如MSSQLServer?我在文档中找不到任何东西,但是由于这个特性包含在许多其他DBMS中,我想我可能遗漏了一些东西。

例:http:/msdn.microsoft.com/en-us/Library/ms 191250.aspx


查看完整描述

3 回答

?
米脂

不超过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生成的列可能与下一次迭代一起出现。有关:

  • 函数调用的属性表示法产生错误

在那之前,你可以模仿VIRTUAL生成的列具有功能使用属性表示法 (tbl.col)看起来和工作方式类似于虚拟生成的列。..由于历史原因,这在Postgres中存在一些语法上的奇怪之处,正好适合这种情况。这个相关的答案代码示例:

  • 将公共查询存储为列?

表达式(看起来像列)不包括在SELECT * FROM tbl尽管如此。你总是必须明确地列出它。

也可以通过匹配来支持表达指数-只要职能是IMMUTABLE..比如:

CREATE FUNCTION col(tbl) ... AS ...  -- your computed expression hereCREATE INDEX ON tbl(col(tbl));

备选方案

或者,您可以使用VIEW,可选地与表达式索引耦合。然后SELECT *可以包括生成的列。

“坚持”(STORED)计算列可以用触发器以一种功能相同的方式。

物化观点是一个密切相关的概念,自Postgres 9.3以来实施.
在早期版本中,可以手动管理MVS。



查看完整回答
反对 回复 2019-10-23
?
噜噜哒

是的,你可以!解决方案应该是简单的,安全的,有效的.

我刚开始使用PostgreSQL,但似乎可以使用表达指数,与视点(视图是可选的,但使生活更容易一些)。

假设我的计算是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);

你可以用解释.

但是,此时您正依赖于表的用户,他们确切地知道如何构造列。为了使生活更容易,您可以创建一个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不用担心它是如何工作的.他们只是得到了良好的表现。视图不复制原始表中的任何数据,因此它具有良好的内存性和性能性。但是请注意,您不能更新/插入到视图中,只能更新到源表中,但如果确实需要,我相信可以使用以下方法将插入和更新重定向到源表规则(我可能在最后一点上错了,因为我自己从未尝试过)。

编辑:如果查询涉及相互竞争的索引,规划者引擎有时可能根本不使用表达式索引。选择似乎依赖于数据。



查看完整回答
反对 回复 2019-10-23
?
MMMHUHU

一种方法是用扳机!

CREATE TABLE computed(
    one SERIAL,
    two INT NOT NULL);CREATE OR REPLACE FUNCTION computed_two_trg()RETURNS triggerLANGUAGE plpgsql
SECURITY DEFINERAS $BODY$BEGIN
    NEW.two = NEW.one * 2;

    RETURN NEW;END$BODY$;CREATE TRIGGER computed_500
BEFORE INSERT OR UPDATEON computedFOR EACH ROWEXECUTE PROCEDURE computed_two_trg();

在更新或插入行之前触发器。它改变了我们想要计算的字段。NEW记录,然后返回那个记录。




查看完整回答
反对 回复 2019-10-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信