23

MySQL で階層データを操作するには、次の 2 つの方法があります。

  1. 隣接リスト モデル
  2. 入れ子集合モデル

隣接リスト モデルの主な問題は、階層のパスを取得するためにノードごとに 1 つのクエリを実行する必要があることです。

ネストされたセット モデルでは、この問題は存在しませんが、追加されたノードごとに、他のすべての左右の値に MySQL UPDATE を与える必要あります

私の階層データは、e コマースの製品カテゴリなどの静的データではありません。ユーザーを階層順に常時登録しています。

私のアプリケーションでは、多くの定数ユーザー登録がありますが、階層内の最初のノードに到達するまでの階層パスも取得する必要があります。

私の状況を分析すると、2 つの選択肢のどちらが私のアプリケーションに最適でしょうか?

4

1 に答える 1

32

入れ子集合モデルは、1 つではなく 2 つの「ポインター」を管理する必要があるという事実を考えると、Adiacency List Model よりも複雑であるため、現在データベースでは一般的に使用されていません。実際、ネストされたセット モデルは、階層を横断する再帰クエリを実行することが複雑または不可能であったときに、データベースに導入されました。

1999 年から、標準 SQL にはいわゆる再帰共通テーブル式 (Recursive CTE) が含まれるようになりました。これにより、任意の数のレベルを持つ階層内の再帰パスをトラバースするクエリをより簡単に (そして標準化して) 作成できます。

現在、すべての主要な DBMS システムにこの機能が含まれていますが、MySQL は例外です。しかし、MySQL では、ストアド プロシージャを使用してこの問題を解決できます。たとえば、StackOverflow に関するこの投稿、またはdba.stackexchange に関するこの投稿を参照してください。

要約すると、これらは私のアドバイスです:

  1. どの DBMS を使用するかをまだ決定できる場合は、いくつかの代替手段を強く検討してください。たとえば、オープン ソース データベースを使い続けたい場合は、PostgreSQLを使用し、Adiacency List Model を使用し、クエリに再帰 CTE を使用します。
  2. DBMS を変更できない場合でも、Adiacency List Model を使用し、参考文献で引用されているストアド プロシージャを使用する必要があります。

アップデート

この状況は、現在開発中でRecursive CTEs を統合する MySQL 8 で変わりつつあり、そのバージョンからは Adiacency List Model がより使いやすくなります。

于 2015-07-26T22:41:32.313 に答える