1

私はPostgreSQLが初めてです。構築する必要があるハイブリッド データベースについて、非常に珍しい要件があります。私が見たモジュールから、次のことが可能であるように思えます。

テーブルに実際にデータを追加せずに、キー - [値] をインデックスに追加できるようにする必要があります。簡単に言えば、理想的には btree (ルックアップ速度) として、キー [値] ストアが必要です。インデックス構造が理想的です。おそらく、別の構造がこれを行うでしょう。

具体的には、次のようなものを保存したいと思います。

KEY     [IDs]
Blue    10, 20, 23, 47
Green   5, 12, 40

このデータを保存してインデックスを作成するオーバーヘッドは必要ありません。いわば「インデックス付けされているが保存されていない」データが必要なだけです。

同様に重要なのは、これらの構造を照会してデータ (ID) を取得し、ID に対して INTERSECTS などを実行したり、キーに対して IN、BETWEEN、= などを実行したりできることです。

お察しのとおり、最終的な目標は ID の最終的なリストであり、それがクライアントに送信され、必要に応じて検索されます。

編集

私がしたくないのは、すべての値のキーを記録することです。上記の例を使用すると、{Blue, 10}、{Blue, 20} などは保存したくありません。{Blue, [10, 20, 23, 47]} を保存したいのです。

これを従来のテーブルとして保存すると、この重複の問題を回避する方法がわかりません。

青 [10, 20, 23, 47]} をもう一度見てみると、これは技術的には、ID (10, 20, 23, 47) が値としてマークされ、親キーが「青」である単一の btree にすぎません。キーとしてマークされています。

このデータ型の不一致は単一のツリーでは厄介になる可能性があるため、理想的な解決策は「[btrees] in a btree」であると思います。ここで、「btree」がキーで、[btrees] は a の値の各グループの btree です鍵。

4

1 に答える 1

3

この方法でどうしてもやりたい場合は、値を配列として格納できます。 intarrayモジュールは、それらを操作するための演算子を提供します。あれは:

create table data(key text primary key, values int[] not null);
insert into data
  values('Blue', '{10,20,23,47}'),('Green','{5,12,40}'),('Red', '{5,10,28}');

これであなたは書くことができます:

select unnest(values) from data where key = 'Blue'
  intersect
  select unnest(values) from data where key = 'Red';

理想的には、int[] をセットに変換し、交差点などを計算する集計関数が必要ですが、提供されていないようです。

実際、これは、より典型的な構造をわずかにコンパクトに格納したものです。

select key, unnest(values) as value from data;
  key  | value
-------+-------
 Blue  |    10
 Blue  |    20
 Blue  |    23
[...]

実際、ビューを上記のクエリとして定義するだけです。

より正規化されたアプローチは、2 つのテーブルを持つことです。1 つはキーを記述し、もう 1 つはキーを値に関連付けます。

create table key_dimension(key_id serial primary key, key text not null unique);
insert into key_dimension(key) values('Blue'),('Green'),('Red');
create table key_value(key_id int not null references key_dimension(key_id), value int not null, primary key(key_id, value));
insert into key_value(key_id, value)
  select key_id, unnest(values) from key_dimension join data using (key);

そしていま:

select value from key_value
  where key_id = (select key_id from key_dimension where key = 'Red')
intersect
select value from key_value
  where key_id = (select key_id from key_dimension where key = 'Blue')

そのため、キー値を選択するクエリはキーのセット (key_dimension) に対してのみ実行する必要があり、最小限の合成キー (key_id) を使用してこれらを (key_value から) 実際のデータ値のセットに変換します。

于 2011-03-13T12:48:13.790 に答える