5

ノード間の子と親の関係を定義するテーブルがあります。

CREATE TABLE node (                           ' pseudo code alert
  id        INTEGER PRIMARY KEY,
  parentID  INTEGER, ' should be a valid id.
)

parentID常に有効な既存のノードを指している場合、これは当然ツリー構造を定義します。

その場合、ノードはルートノードでparentIDあるNULLと見なすことができます。

どのように私は:

  1. 特定のノードの子孫であるすべてのノードを検索しますか?
  2. 特定の深さまでの特定のノードの下にあるすべてのノードを検索しますか?

これらのそれぞれを単一のSQL(必然的に再帰的であると思います)または2つの相互再帰クエリとして実行したいと思います。

これはODBCコンテキストで行っているため、ベンダー固有の機能に依存することはできません。

編集

  • テーブルはまだ作成されていないため、列/テーブルを追加することはまったく問題ありません。
  • ツリーは潜在的に更新され、頻繁に追加されます。補助的なデータ構造/テーブル/列は可能ですが、最新の状態に保つ必要があります。この種の質問のために手が届く魔法の本があれば、私は知りたいです。

どうもありがとう。

4

3 に答える 3

4

このリンクは、隣接リスト モデル (質問で説明されているように) とネストされたセット モデルの両方に関するチュートリアルを提供します。これは、MySQL のドキュメントの一部として書かれています。

その記事で議論されていないのは、挿入/削除時間、および 2 つのアプローチのメンテナンス コストです。例えば:

  • ネストされたセット モデルを使用して動的に成長するツリーは、ネストを維持するためにメンテナンスが必要なようです (たとえば、すべての左と右のセット番号を付け直す)。
  • 隣接リスト モデルでノードを削除するには、少なくとも 1 つの他の行を更新する必要があります。
于 2009-01-19T12:38:34.970 に答える
2

この種のクエリに到達する魔法の本がある場合は、知りたい.

SmartiesのためのSQLのCelkoのツリーと階層

于 2009-01-19T00:31:33.067 に答える
1

ルート ノードの ID からの「パス」全体を別の列に保存し、先頭と末尾にも必ずセパレータを使用してください。たとえば、1 が 17 の親である 5 の親であり、区切り文字がダッシュであるとしましょう。パス列に値 -1-5-17- を格納します。

5 のすべての子を検索するには、パスに -5- が含まれるレコードを選択するだけです。

LIKE を使用するときに、フィールドの左端または右端にある ID について心配する必要がないように、両端のセパレーターが必要です。

深さの問題に関しては、現在のネストの深さを示す深さの列をテーブルに追加すると、これも簡単になります。開始ノードの深さを調べてから x を追加します。ここで、x は検索するレベルの深さの数であり、それより深い深さのレコードを除外します。

于 2009-01-19T13:19:33.593 に答える