SQLでデータツリーを表現する方法は?


2 Answers

SQL-Antipatternsに関するこのslidshareをブックマークしました。これは、いくつかの選択肢について説明していhttp://www.slideshare.net/billkarwin/sql-antipatterns-strike-back?src=embed : http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back?src=embed src=embed

そこからの推奨事項は、Closure Table(スライドで説明されています)を使用することです。

ここに概要があります(スライド77):

                  | Query Child | Query Subtree | Modify Tree | Ref. Integrity
Adjacency List    |    Easy     |     Hard      |    Easy     |      Yes
Path Enumeration  |    Easy     |     Easy      |    Hard     |      No
Nested Sets       |    Hard     |     Easy      |    Hard     |      No
Closure Table     |    Easy     |     Easy      |    Easy     |      Yes
Question

私はツリーとTreeNodeから結合されたデータツリー構造を書いています。 ツリーには、データのルートアクションと最上位レベルのアクションが含まれます。 私はTreeViewにツリーをバインドすることができるWindowsフォームでツリーを表示するUIライブラリを使用しています。

このツリーとノードをDBに保存する必要があります。 ツリーを保存し、次の機能を得るための最良の方法は何でしょうか。

  1. 直観的な実装。
  2. 簡単なバインディング。 ツリーからDB構造に移動して戻ることができます(もしあれば)

私には2つのアイデアがあった 1つは、テーブル内の1つのライナーにデータをシリアル化することです。 2番目はテーブルに保存することですが、データエンティティに移動すると、変更されたノードのテーブルの行状態が失われます。

何か案は?




PostgreSQLを使用している場合、ツリー構造を実装しているcontrib拡張(デフォルトでは提供されています)内のパッケージであるltreeを使用することができます。

docsから:

CREATE TABLE test (path ltree);
INSERT INTO test VALUES ('Top');
INSERT INTO test VALUES ('Top.Science');
INSERT INTO test VALUES ('Top.Science.Astronomy');
INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics');
INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology');
INSERT INTO test VALUES ('Top.Hobbies');
INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy');
INSERT INTO test VALUES ('Top.Collections');
INSERT INTO test VALUES ('Top.Collections.Pictures');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts');
CREATE INDEX path_gist_idx ON test USING GIST (path);
CREATE INDEX path_idx ON test USING BTREE (path);

次のようなクエリを実行できます。

ltreetest=> SELECT path FROM test WHERE path <@ 'Top.Science';
                path
------------------------------------
 Top.Science
 Top.Science.Astronomy
 Top.Science.Astronomy.Astrophysics
 Top.Science.Astronomy.Cosmology
(4 rows)



テーブル「ノード」のようなもの。各ノードの行には、(通常のノードデータに加えて)親IDが含まれています。 rootの場合、親はNULLです。

もちろん、これは子どもたちにもう少し時間を掛けることになりますが、この方法では実際のデータベースは非常にシンプルになります。




Related