支援版本: 目前 (17) / 16 / 15 / 14 / 13
開發版本: devel
不支援版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.18. intagg — 整數聚合器和枚舉器 #

intagg 模組提供整數聚合器和枚舉器。intagg 現在已過時,因為有內建函數提供其功能的超集合。但是,該模組仍然作為內建函數的相容性包裝提供。

F.18.1. 函數 #

聚合器是一個聚合函數 int_array_aggregate(integer),它產生一個整數陣列,其中包含它所接收的整數。 這是 array_agg 的包裝函式,它對任何陣列類型執行相同的操作。

枚舉器是一個函數 int_array_enum(integer[]),它返回 setof integer。 它本質上是聚合器的反向操作:給定一個整數陣列,將其展開為一組行。 這是 unnest 的包裝函式,它對任何陣列類型執行相同的操作。

F.18.2. 使用範例 #

許多資料庫系統都有多對多表的概念。 這樣的表通常位於兩個索引表之間,例如

CREATE TABLE left_table  (id INT PRIMARY KEY, ...);
CREATE TABLE right_table (id INT PRIMARY KEY, ...);
CREATE TABLE many_to_many(id_left  INT REFERENCES left_table,
                          id_right INT REFERENCES right_table);

它通常像這樣使用

SELECT right_table.*
FROM right_table JOIN many_to_many ON (right_table.id = many_to_many.id_right)
WHERE many_to_many.id_left = item;

這將傳回左側表中條目右側表中的所有項目。 這是 SQL 中非常常見的結構。

現在,如果 many_to_many 表中有大量條目,此方法可能會很麻煩。 通常,像這樣的聯結會導致索引掃描,並為特定左側條目的表中每個右側條目提取。 如果您有一個非常動態的系統,您就無能為力。 但是,如果您有一些相當靜態的資料,則可以使用聚合器建立摘要表。

CREATE TABLE summary AS
  SELECT id_left, int_array_aggregate(id_right) AS rights
  FROM many_to_many
  GROUP BY id_left;

這將建立一個表,每個左側項目一行,以及一個右側項目陣列。 現在,如果沒有使用該陣列的方法,這幾乎是無用的; 這就是為什麼有一個陣列枚舉器的原因。 你可以做

SELECT id_left, int_array_enum(rights) FROM summary WHERE id_left = item;

上述使用 int_array_enum 的查詢產生與以下查詢相同的結果

SELECT id_left, id_right FROM many_to_many WHERE id_left = item;

不同之處在於,針對摘要表執行的查詢必須僅從表中獲取一行,而針對 many_to_many 執行的直接查詢必須為每個條目進行索引掃描並提取一行。

在一個系統上,EXPLAIN 顯示成本為 8488 的查詢已降低到成本為 329。 原始查詢是涉及 many_to_many 表的聯結,該表已替換為

SELECT id_right, count(id_right) FROM
  ( SELECT id_left, int_array_enum(rights) AS id_right
    FROM summary
    JOIN (SELECT id FROM left_table
          WHERE id = item) AS lefts
    ON (summary.id_left = lefts.id)
  ) AS list
  GROUP BY id_right
  ORDER BY count DESC;

提交更正

如果您在文件中發現任何不正確、與特定功能的使用經驗不符或需要進一步說明的資訊,請使用此表單回報文件問題。