2011-06-26 35 views
1
CREATE TABLE sectors 
(
    sector_id integer PRIMARY KEY, 
    sector_name varchar(100) NOT NULL, 
    parent_sector_id integer REFERENCES sectors(sector_id) 
); 

INSERT INTO sectors(sector_id, sector_name, parent_sector_id) 
SELECT 1, 'All sectors', NULL UNION ALL 
SELECT 2, 'Business', 1 UNION ALL 
SELECT 3, 'Manufacturing', 2 UNION ALL 
SELECT 4, 'Retail', 2 UNION ALL 
SELECT 5, 'Trading', 1 UNION ALL 
SELECT 6, 'Nonprofit', 1 UNION ALL 
SELECT 7, 'Agriculture', 1; 

質問1:機能を経由して親の関係を探すPostgreSQLの階層関係の機能

SELECT is_parent(1/*All sectors*/, 4/*Retail*/) should be true 
SELECT is_parent(2/*Business*/, 4/*Retail*/) should be true 

質問2:

SELECT is_child(4/*Retail*/, 1/*All sectors*/) should be true 
SELECT is_child(4/*Retail*/, 2/*Business*/) should be true 

この上の任意のヘルプは、次のようになり機能を介した親子関係を探します高く評価。

答えて

2

...再帰クエリを使用して

は、is_parent()非常にに高速になるだろう。 parent_sector_idにインデックスがあると仮定すると、基本的に深度レベルごとに1つのインデックススキャンを行います。

is_child()これに対して、単純な方法で実装し、大きなツリーを持っていると、すべての子供をつかんでノードをチェックしていないと、非常に遅くなります。

このようなツリーがあり、すべての子を取得する必要がある場合は、あらかじめ順序付けされたツリーアルゴリズム(浮動小数点数または整数を使用します。これは、書き込みが非常に遅くなるため整数ではありません) 。

もしそうでない場合は、引数を逆にしてis_parent()を呼び出します。つまり、sql関数is_child(a, b)is_parent(b, a)を返します。

最後に重要なのは、contribにltree datatypeが含まれていることです。それを使用して、任意のノード上の要点インデックスを持つis_parent/is_childクエリを実行できます。

+0

+1 ltreeデータ型については、残念ながら、私はそれをここで使うことはできません。感謝のデニス。 :) –

3

このような種類の質問に本当に答える必要がある場合は、PostgreSQL's recursive queriesをご覧ください。実際にそれらの関数(is_parentis_child)を書く必要がある宿題の場合は、再帰的クエリを使用して実装することをお勧めします。パブロの応答に追加

関連する問題