2011-03-13 7 views
1

私はPostgreSQLを初めて使用しています。私は構築する必要のあるハイブリッドデータベースに対して非常に珍しい要件があります。私が見たモジュールから、は私にはと思われますが、次のことが可能です。ハイブリッド "インデックスのような" btree構造 - PostgreSQLでこれを行うことができますか?

実際にテーブルにデータを追加することなく、インデックスにkey - [values]を追加できる必要があります。簡単に言えば、私はキー[値]ストアが必要です。理想的にはbtree(ルックアップスピード)です。インデックス構造が理想的です。おそらく別の構造がこれを行うでしょう。私は、このデータとインデックス、それを格納するオーバーヘッドをしたくない

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

は非常に具体的には、私のようなものを保存したいです。私はちょうど話すために、データを「索引は付いているが記憶していない」必要がある。

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

おそらく推測することができますが、最終目標はIDの最終リストです。これがクライアントに送信され、意向を参照します。私はしたくない何

EDIT

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

これを伝統的なテーブルとして保存すると、この重複した問題を回避する方法はありません。

これは、技術的には、ID(10,20,23,47)が値としてマークされている単一のbtreeだけで、青色[10,20,23,47]キー「青」がキーとしてマークされます。

このデータ型の不一致は1つのツリーでは厄介かもしれないので、理想的な解決策は "btree"がキーで、 "btree"が各グループのbtreeであるキーの値の

+0

私のコメントと紛らわしいのは、私が述べているようにデータを操作することができないと考えることです。技術的に私がここで求めているのは、それぞれbtreeの値を持つbtreeのキーです。この値は、さらにSQL操作に参加できます。私が望む構造はM/MUMPSと同じです。これのために – IamIC

答えて

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 
[...] 

は、実際には、あなたは、単に上記のクエリするビューを定義することができます。

は本当に、これはより一般的な構造のちょうどもう少しコンパクトに収納されます。値とそれらを関連付けるためのキー、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); 

となりました:

より正規化されたアプローチは、2つのテーブルを持っているだろう

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の)データ値の実際のセットに変換します。

+0

ありがとう。はい、私は正規化されたアプローチを使用してこれを実装します。私は不健全な経験はありません。そのパフォーマンスがより伝統的な「キー、値」パターンを使用してこれを保存することと比較し、それに対するINTERESCTを実行する方法を知っていますか?パフォーマンスの観点からは、配列をソートしたままにする必要がありますか? – IamIC

+1

私は正直言って、もし、入出力を減らすことが重視される問題であれば、それは実行可能でなければなりません。実装を代表データと比較するための代替手段は実際にはありません。 – araqnid

+0

ありがとうございました。私はこのソリューションが私のニーズに合っていると思います。もちろん、いくつかのR&Dがありますが、私が必要としていることをカバーするものはカバーしています。 – IamIC

関連する問題