# F.17.英塔格

F.17.1.功能F.17.2.样本使用

这个英塔格模块提供一个整数聚合器和一个枚举器。英塔格现在已经过时了,因为有一些内置函数可以提供其功能的超集。然而,该模块仍然作为内置函数的兼容性包装器提供。

# F.17.1.功能

聚合器是一个聚合函数整数数组集合(整数)这将生成一个整数数组,该数组正好包含输入的整数。这是包装纸数组_agg,它对任何数组类型都执行相同的操作。

枚举数是一个函数int_数组_枚举(整数[])又回来了整数集它本质上是聚合器的反向操作:给定一个整数数组,将其展开为一组行。这是包装纸不安,它对任何数组类型都执行相同的操作。

# F.17.2.样本使用

许多数据库系统都有一对多表的概念。这样的表通常位于两个索引表之间,例如:

CREATE TABLE left (id INT PRIMARY KEY, ...);
CREATE TABLE right (id INT PRIMARY KEY, ...);
CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);

它通常是这样使用的:

SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
  WHERE one_to_many.left = item;

这将返回右表中的所有项目,以获得左表中的一个条目。这是SQL中非常常见的构造。

现在,这种方法可能会很麻烦,因为数据库中有大量条目一对多桌子通常,这样的连接会导致索引扫描,并为表中的每个右项获取特定的左项。如果你有一个非常动态的系统,你能做的就不多了。但是,如果您有一些相当静态的数据,可以使用聚合器创建一个汇总表。

CREATE TABLE summary AS
  SELECT left, int_array_aggregate(right) AS right
  FROM one_to_many
  GROUP BY left;

这将创建一个表,每个左项一行,右项一个数组。如果没有使用数组的方法,这是非常无用的;这就是为什么有一个数组枚举器。你能行

SELECT left, int_array_enum(right) FROM summary WHERE left = item;

上面的查询使用整数数组枚举产生的结果与

SELECT left, right FROM one_to_many WHERE left = item;

不同之处在于,对汇总表的查询只能从表中获取一行,而对一对多必须对每个条目进行索引扫描并获取一行。

在一个系统上解释显示一个成本为8488的查询被减少到了329.原始查询是一个涉及一对多表,替换为:

SELECT right, count(right) FROM
  ( SELECT left, int_array_enum(right) AS right
    FROM summary JOIN (SELECT left FROM left_table WHERE left = item) AS lefts
         ON (summary.left = lefts.left)
  ) AS list
  GROUP BY right
  ORDER BY count DESC;