ホームページ  >  記事  >  バックエンド開発  >  ツリーデータ構造の格納方法(クエリ)

ツリーデータ構造の格納方法(クエリ)

藏色散人
藏色散人転載
2019-09-07 11:05:303318ブラウズ

隣接リスト モデル

日常のビジネス開発では、階層構造を持つツリー状のデータに遭遇することがよくあります。リレーショナル データベースに格納される場合、このデータ構造は多くの場合、次のような隣接リストと呼ばれるモデルに格納されます。

CREATE TABLE `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` char(100) NOT NULL,
  `pid` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

ツリーデータ構造の格納方法(クエリ)

このモデルは次のことを表します。図は次のとおりです。

ツリーデータ構造の格納方法(クエリ)

# このデータ モデルについては多くの人がすでによく知っていると思うので、ここでは詳しく説明しません。次のデータ モデルに注目してみましょう。

ネストされたセット モデル

ツリーを表す別の方法は、ツリーをセットとして保存することです。次のテーブル構造を再定義します:

CREATE TABLE `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` char(100) NOT NULL,
  `lft` int(11) NOT NULL UNIQUE CHECK (lft> 0),
  `rgt` int(11) NOT NULL UNIQUE CHECK (rgt> 1),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

ツリーデータ構造の格納方法(クエリ)

そして、このモデルの図は次のようになります:

ツリーデータ構造の格納方法(クエリ)

lft と rgt はセットの境界として使用され、この 2 つの差が大きいほどセットが大きくなり、セット内の要素が多くなります。

サブセットに従って、親カテゴリを見つけます

SELECT c2.* 
  FROM categories as c1, categories as c2
  WHERE c1.lft BETWEEN c2.lft and c2.rgt 
      AND c1.title = '华为';
+----+-------------+-----+-----+
| id | title       | lft | rgt |
+----+-------------+-----+-----+
|  1 | Smartphones |   1 |  14 |
|  5 | Harmony OS  |  10 |  13 |
|  8 | 华为        |  11 |  12 |
+----+-------------+-----+-----+

親に従って、その下のすべてのサブセットを見つけます

SELECT c1.*
   FROM categories AS c1, categories AS c2
  WHERE c1.lft BETWEEN c2.lft AND c2.rgt
    AND c2.title = 'Smartphones';
+----+-------------+-----+-----+
| id | title       | lft | rgt |
+----+-------------+-----+-----+
|  1 | Smartphones |   1 |  14 |
|  3 | Android     |   2 |   5 |
|  4 | iOS         |   6 |   9 |
|  5 | Harmony OS  |  10 |  13 |
|  6 | 小米        |   3 |   4 |
|  7 | iPhone      |   7 |   8 |
|  8 | 华为        |  11 |  12 |
+----+-------------+-----+-----+

各カテゴリのレベルを表示

 SELECT COUNT(c2.id) AS indentation, c1.title
  FROM categories AS c1, categories AS c2下周三we'fv
  WHERE c1.lft BETWEEN c2.lft AND c2.rgt
  GROUP BY c1.title
  ORDER BY c1.lft;
+-------------+-------------+
| indentation | title       |
+-------------+-------------+
|           1 | Smartphones |
|           2 | Android     |
|           3 | 小米        |
|           2 | iOS         |
|           3 | iPhone      |
|           2 | Harmony OS  |
|           3 | 华为        |
+-------------+-------------+

利点と欠点

隣接リスト モデル

隣接リスト モデルは理解しやすく、必要なコードも非常に複雑です。単純。

しかし、ほとんどのプログラミング言語では、速度が遅く、非効率的です。これは主に再帰によって発生します。ツリー内の各ノードに対してデータベース クエリを実行する必要があります。

これにより、大きなツリーを扱う場合、各クエリに時間がかかるため、関数が非常に遅くなる可能性があります。関数ごとに、数値を取得するために再帰的アルゴリズムが必要になるためです。

もちろん、List のような再帰に適した言語を使用する場合は、このデータ モデルの欠点を無視できます。ただし、PHP の場合、このデータ モデルの処理全体が非常に遅くなります。

ネストされたセット モデル

隣接リスト モデルと比較すると、このデータ モデルは明らかにそれほど理解しやすいものではありません。また、データを追加するのはそう簡単ではなく、追加するときに左側と右側の値を計算し、後続の値を移動する必要があるため、データを追加するプレッシャーが高まります。

同様に、これがもたらす利点は、単純なクエリでツリー クエリを完了できることと、2 つのパラメータ lft と rgt に基づいてサブ要素の数を計算できることです。

概要

両方のモデルにはそれぞれ長所と短所があり、1 つは挿入よりも優れており、もう 1 つはクエリよりも優れています。私はネストされたセット モデルを好みますが、それでも特定のビジネスに基づいて選択する必要があります。

以上がツリーデータ構造の格納方法(クエリ)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。