1

現在の構造から完全なツリーを取得したり、現在のテーブル構造をリファクタリングして最適化された再帰クエリを可能にしたりするにはどうすればよいでしょうか?

問題

反復せずにベース コンポーネントからコンポーネントの完全なツリーを取得できません。

1 つのコンポーネントは、定義されていない数の接続 (深さ) を持つことができます。

各コンポーネントは複数のコンポーネントに関連付けることができるため、コンポーネントには親プロパティがありません。

コンポーネントの影響を受ける属性値を再帰的に更新できません。たとえば、コンポーネントの価格が変更された場合、関連するすべての components_of の価格が更新されます。

現在の体制

成分

primary key (id)
| id | price |
|----|------ |
| A  | 1     |
| B  | 1     |
| C  | 1     |
| D  | 2     |
| E  | 2     |

component_closure

unique index (component, component_of)
index (component_of)
FK (component) References component (id)
FK (component_of) References component (id)
| component | component_of |
|--------------------------|
|     D     |  B           |
|     D     |  C           |
|     B     |  A           |
|     E     |  C           |
|     E     |  A           |

結果のグラフ モデル:

グラフ

クエリの例:

UPDATE component
SET price = 2
WHERE id = 'A';

望ましい結果(*は再帰的に更新された値を示します)

| id | price |
|----|------ |
| A  | 2     |
| B  | 2     | *
| C  | 1     |
| D  | 3     | *
| E  | 3     | * 

すべてのコンポーネントの component_of 関係を取得し、深さ列を使用してコンポーネントの順序を決定できるように、ツリー関係全体を component_closure テーブルに格納する必要があると考えています。即時の components_of など、完全なツリーが必要ない場合は無駄に思えますが。

例えば:

| component | component_of | depth |
|-----------|--------------|-------|
|  D        | A            | 1     |
|  D        | B            | 2     |
|  D        | C            | 1     |
4

1 に答える 1

1

はい、推移閉包を保存したい場合は、すべてのパスを保存する必要があります。

一部の操作では、長さ 0 のパスを保存すると便利です。

| component | component_of | depth |
|-----------|--------------|-------|
|  D        | D            | 0     |
|  D        | A            | 1     |
|  D        | B            | 2     |
|  C        | C            | 0     |
|  B        | B            | 0     |
|  B        | A            | 1     |
|  A        | A            | 0     |

MySQL 8.0 では、これは必要ありません。最終的に再帰クエリを使用できるようになります。

于 2017-08-03T17:43:04.957 に答える