intagg
模組提供了一個整數聚合器和一個列舉器。 intagg
現在已過時,因為有一些內建函數提供了其功能的超集合。但是,該模組仍然作為內建函數的相容性包裝器提供。
聚合器是一個彙總函數 int_array_aggregate(integer)
,它產生一個整數陣列,其中包含它所接收到的所有整數。 這是 array_agg
的包裝器,對於任何陣列類型,它都可以執行相同的操作。
列舉器是一個函數 int_array_enum(integer[])
,它返回 setof integer
。 它本質上是聚合器的反向操作:給定一個整數陣列,將其展開為一組列。 這是 unnest
的包裝器,對於任何陣列類型,它都可以執行相同的操作。
許多資料庫系統都有多對多表格的概念。 這樣的表格通常位於兩個索引表格之間,例如
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;
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的地方,請使用 此表格回報文件問題。