10

私はPHP/MySQL/Javascriptでプログラミングしています。ティアの数に制限のない、子/親の関係でリンクしたいパーツのリストがあります。

パーツのリストから選択して子を親に追加する場合、パーツのリストを制限して、親自体と、すでにその親の子であるパー​​ツを除外します。

私が発見したのは、親の祖父母も除外したいということです。そうしないと、近親相姦の関係が得られ、パーツのツリーを表示すると無限ループが作成されます。

それだけでなく、子の部分を親の曽祖父母や曽祖父母にすることはできません。

これが私が現在使用しているSQLステートメントです。これを使用することで改善できると思いますが、現時点ではSQLに精通してLEFT JOINいません。

SELECT * 
FROM sch_part_general 
WHERE (sch_part_general.part_id <> $parentId) 
AND (sch_part_general.part_id NOT IN 
  (SELECT part_id FROM sch_part_mapping WHERE parent_id = $parentId)
)

sch_part_generalは、part_idを主キーとする、すべての部分を含む複数列のテーブルです。sch_part_mappingは、part_id(子)を持つ2列のマッピングテーブルです|| parent_id(親)。

誰かがSQLクエリで私を正しい方向に向けることができますか?これは非常に非効率的だと思うので、whileループを使用してSQLステートメントを作成することに熱心ではありませんが、これがこれまでのところ機能すると考えた唯一の方法です。

4

3 に答える 3

6

MySQL階層クエリは(あるとしても)あまりサポートされていません。と呼ばれるものに固執したい場合は、含めるレベルごとにをAdjacency List Model追加するだけです。JOIN言うまでもなく、これはうまくスケーリングしません。

一方、データベーススキーマを変更できる場合は、を実装することをお勧めしますNested Set Model

の非常に優れた外植は、MikeHillyerのブログNested Set Modelに掲載されています。

隣接リストモデルの制限

純粋なSQLで隣接リストモデルを操作することは、せいぜい難しい場合があります。カテゴリのフルパスを表示する前に、そのカテゴリが存在するレベルを知る必要があります。

入れ子集合モデル

SQLの入れ子集合の概念は、10年以上前から存在しており、書籍やインターネットで利用できる追加情報がたくさんあります。私の意見では、階層情報の管理に関する最も包括的な情報源は、高度なSQLの分野で非常に尊敬されている著者であるJoe Celkoによって書かれた、Joe Celko's Trees and Hierarchies in SQLforSmartiesという本です。

于 2012-07-25T14:55:31.597 に答える
1

スキーマを変更できない場合は、Lievenからの回答が示唆しているように、ループから逃げることはありません。

スキーマを変更できる場合は、次の場合でも十分です。sch_part_mappingに新しい列を追加し、「hierarchy_id」と呼びましょう。これは、まったく新しい階層を最初に開始したときに一意のintになるように構築された値であり(任意の階層で最初のグランドグランドグランドグランドモストの親がありますが、英語で言われています)、単一の階層に属するすべての行に挿入されます。どのレベルで問題になります。

次に、同じ階層にある親と祖父母をスキップするのは簡単です。上記のSQLに、次を追加できます。

SELECT * 
FROM sch_part_general 
WHERE (sch_part_general.part_id <> $parentId) 
AND (sch_part_general.part_id NOT IN 
  (SELECT part_id FROM sch_part_mapping WHERE parent_id = $parentId)

//addition here 
and not exists (select * from sch_part_mapping where hierarchy_id= ? and parent_id = sch_part_general.part_id)

)

疑問符は、計算する必要のある関連する階層IDに置き換える必要があります。

編集:特定の親IDの変数があるのを見逃したので、hierarchy_idは同じクエリで計算できます:

SELECT * 
    FROM sch_part_general 
    WHERE (sch_part_general.part_id <> $parentId) 
    AND (sch_part_general.part_id NOT IN 
      (SELECT part_id FROM sch_part_mapping WHERE parent_id = $parentId)

    //addition here 
    and not exists (select * from sch_part_mapping where hierarchy_id= (select hierarchy_id from sch_part_mapping where parent_id = $parentId limit 1) and parent_id = sch_part_general.part_id)


)
于 2012-07-25T16:17:36.973 に答える
0

MySql / MariaDBを使用すると、Open Query Graphエンジン(http://openquery.com/graph/doc)を使用できます。これは、基本的にparentIdとchildIdの関係を配置する特別なテーブルを作成できるmysqlプラグインです。

魔法は、クエリで渡された値に応じて特別な列ラッチを使用してこのテーブルをクエリし、実行するコマンドをOQGRAPHエンジンに指示することです。詳細については、ドキュメントを参照してください。

ツリー(再帰的な1-n関係)だけでなく、重み付きのグラフデータ構造(再帰的なnm関係)も処理します(たとえば、会社の所有権を保存する場合、会社は複数の子会社を持つことができ、複数の株主を持つこともできます)。

于 2013-04-04T12:02:02.707 に答える