The <filename>intagg</filename> module provides an integer aggregator and an
enumerator. <filename>intagg</filename> is now obsolete, because there
are built-in functions that provide a superset of its capabilities.
However, the module is still provided as a compatibility wrapper around
the built-in functions.
intagg
モジュールは整数型の集約子と列挙子を提供します。
その能力の上位集合を提供する組み込み関数が存在しますので、intagg
は現在使われません。
しかし、このモジュールは組み込み関数の互換ラッパーとして今でもまだ提供されています。
The aggregator is an aggregate function
<function>int_array_aggregate(integer)</function>
that produces an integer array
containing exactly the integers it is fed.
This is a wrapper around <function>array_agg</function>,
which does the same thing for any array type.
集約子は、正確に提供する整数のみを含む整数型配列を生成するint_array_aggregate(integer)
集約関数です。
これは任意の配列型で同じことを行うarray_agg
のラッパーです。
The enumerator is a function
<function>int_array_enum(integer[])</function>
that returns <type>setof integer</type>. It is essentially the reverse
operation of the aggregator: given an array of integers, expand it
into a set of rows. This is a wrapper around <function>unnest</function>,
which does the same thing for any array type.
列挙子は、setof integer
を返すint_array_enum(integer[])
関数です。
これは基本的に上記集約子の反対の操作を行います。
指定された整数型配列を行集合に拡張します。
これは任意の配列型で同じことを行うunnest
のラッパーです。
Many database systems have the notion of a many to many table. Such a table usually sits between two indexed tables, for example: 多くのデータベースシステムは多対多のテーブルを持ちます。 こうしたテーブルは通常、以下のように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);
It is typically used like this: 通常以下のように使用されます。
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
;
This will return all the items in the right hand table for an entry in the left hand table. This is a very common construct in SQL. これは、左辺のテーブル内にある項目に対応した、右辺のテーブル内のすべての項目を返します。 これはSQLで非常によく使用される式です。
Now, this methodology can be cumbersome with a very large number of
entries in the <structname>many_to_many</structname> table. Often,
a join like this would result in an index scan
and a fetch for each right hand entry in the table for a particular
left hand entry. If you have a very dynamic system, there is not much you
can do. However, if you have some data which is fairly static, you can
create a summary table with the aggregator.
さて、この方法論は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;
This will create a table with one row per left item, and an array of right items. Now this is pretty useless without some way of using the array; that's why there is an array enumerator. You can do これは左辺項目毎に1行を持ち、右辺の項目の配列をもつテーブルを作成します。 さて、これは配列を使用する何らかの方法がないとかなり使い勝手が悪くなります。 これが配列列挙子が存在する理由です。 以下を行うことができます。
SELECT id_left, int_array_enum(rights) FROM summary WHERE id_left = item
;
The above query using <function>int_array_enum</function> produces the same results
as
上のint_array_enum
を使用した問い合わせは、以下と同じ結果を生成します。
SELECT id_left, id_right FROM many_to_many WHERE id_left = item
;
The difference is that the query against the summary table has to get
only one row from the table, whereas the direct query against
<structname>many_to_many</structname> must index scan and fetch a row for each entry.
違いは、要約テーブルに対する問い合わせはテーブルから1行だけを取り出す必要があるのに対し、直接many_to_many
に問い合わせる場合はインデックススキャンと各項目に対し行を取り出さなければならないという点です。
On one system, an <command>EXPLAIN</command> showed a query with a cost of 8488 was
reduced to a cost of 329. The original query was a join involving the
<structname>many_to_many</structname> table, which was replaced by:
あるシステムでは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;