問題
注:PostgreSQLのシーケンスメカニズムではなく、数学的なシーケンスを参照しています。
整数のシーケンスを表すテーブルがあります。定義は次のとおりです。
CREATE TABLE sequences
(
id serial NOT NULL,
title character varying(255) NOT NULL,
date date NOT NULL,
sequence integer[] NOT NULL,
CONSTRAINT "PRIM_KEY_SEQUENCES" PRIMARY KEY (id)
);
私の目標は、指定されたサブシーケンスを使用して行を見つけることです。つまり、sequence
フィールドが指定されたサブシーケンスを含むシーケンスである行(私の場合、シーケンスは順序付けされています)。
例
テーブルに次のデータが含まれているとします。
+----+-------+------------+-------------------------------+
| id | title | date | sequence |
+----+-------+------------+-------------------------------+
| 1 | BG703 | 2004-12-24 | {1,3,17,25,377,424,242,1234} |
| 2 | BG256 | 2005-05-11 | {5,7,12,742,225,547,2142,223} |
| 3 | BD404 | 2004-10-13 | {3,4,12,5698,526} |
| 4 | BK956 | 2004-08-17 | {12,4,3,17,25,377,456,25} |
+----+-------+------------+-------------------------------+
したがって、指定されたサブシーケンスが{12, 742, 225, 547}
である場合、行2を検索します。
同様に、指定されたサブシーケンスがである場合、{3, 17, 25, 377}
行1と行4を検索します。
最後に、指定されたサブシーケンスがの場合、{12, 4, 3, 25, 377}
返される行はありません。
調査
まず、配列データ型でシーケンスを表すことが賢明であるかどうかは完全にはわかりません。これは状況に適しているように見えますが、取り扱いが複雑になるのではないでしょうか。おそらく、別のテーブルとの関係のモデルを使用して、シーケンスを異なる方法で表す方が良いでしょう。
同様に、unnest
配列関数を使用してシーケンスを拡張し、検索条件を追加することを考えています。それにもかかわらず、シーケンス内の項の数が可変であるため、その方法がわかりません。
intarrayモジュールのsubarray
関数を使用してシーケンスをサブシーケンスにカットすることも可能ですが、検索にどのように役立つかわかりません。
制約
現時点で私のモデルがまだ開発中である場合でも、テーブルは50,000から300,000行までの多くのシーケンスで構成されることが意図されています。だから私は強力なパフォーマンスの制約があります。
私の例では、比較的小さな整数を使用しました。実際には、これらの整数は、オーバーフローするまではるかに大きくなる可能性がありbigint
ます。そのような状況では、数値を文字列として保存するのが最善だと思います(これらの一連の数学演算を実行する必要がないため)。ただし、このソリューションを選択すると、前述のintarrayモジュールを使用できなくなります。
numeric
文字列ではなく(text
たとえば)使用するのですか?シーケンスで数学演算を実行する必要はありません。
text
、偽の非数値データを格納することを妨げます。場合によっては、I / O のみを実行している場合は、I / O処理を減らすためにテキストが必要になることがあります。
SELECT ARRAY[12, 4, 3, 17, 25, 377, 456, 25] @> ARRAY[12, 4, 3, 25, 377];
この演算子は注文を考慮しないため、trueを返します。
bigint
する可能性がある場合はnumeric
、それらを格納するタイプとして使用する必要があります。ただし、速度はかなり遅くなり、場所が大きくなります。