
ちょうど2時間前、 PHPixie ORMの新しいタイプの通信-ネストセットに最後のテストを追加しました。 SQLデータベースにツリーを保存するために、このアプローチを使用するかクロージャーテーブルを使用するかを長い間考えていました。 しかし、結果として、リンクテーブルが成長する準2次次元のためにクロージャーテーブルが失われます(最悪の場合20ノードで、190レコードが既に取得可能です)。 そのため、次のタスクは、従来のネストされたセットのアプローチを最適化することでした。
ネストされたセットの使用に関する主な問題の1つは、ノードを挿入するコストです。 挿入位置が左にあるほど、より多くのレコードを右にシフトする必要があります。 たとえば、次のようなツリーがあります。

FaxサブカテゴリをPixiesに挿入する必要があるとしましょう。結果は次のとおりです。

ご覧のとおり、ツリー内のすべてのノードを変更する必要があります。 このようにして、記事のコメントツリーを保存するとします。 誰かが新しいコメントを追加するたびに、レコードのヒープの更新が発生します。さらに、トランザクションでこれをすべて確実に実行する必要があります。これらの行への変更は並列要求によって禁止することをお勧めします。 これがすべて完了していない場合、複数のアクティブユーザーが同時にコメントを付けても、すべてのインデックス作成が簡単に破られる可能性があります。 また、システムのパフォーマンスも明らかに非常に影響を受けます。
標準のネストされたセットを少し変更するだけで、この問題を解決するエレガントな方法を見つけました。 一部の場所では実装が著しく困難ですが、そのアイデアは単純です。 すべてのノードに、それらが配置されているサブツリーの識別子(ルートIDなど)を追加します。 各サブツリーで、左と右に番号を付け直します。 このアプローチを使用した上記の例は次のようになります。

挿入時には、同じサブツリーにあるノードのみを変更する必要があります。

ご覧のとおり、Plantsサブツリーはまったく変更されていません。 実用的な観点から、これにより、データベース内の変更された行の数が大幅に削減されます。 異なるサブツリーで変更が行われた場合、それらは互いに干渉せず、それらの1つでインデックスが破損しても、他のサブツリーには影響しません。
これらの設備については、より複雑なコードで支払う必要があります。 ノードを別のサブツリーに転送するとき、またはルートに移動するときに、間違えやすく、 ルートフィールドの変更を忘れがちです。レコードをオブジェクトツリーに変換する手順も少し複雑です。 そのため、すべてのケースのテストを作成するのに非常に時間がかかりました。
PHPixieでの使用
すぐに完全なドックがサイトに表示されますが、新しい接続を今すぐ使用したい人のための小さなガイドがあります。
最初に、要素が保存されているテーブルに4つのINTEGERフィールドを追加します: left 、 right 、 rootId 、 depth (もちろん、フィールド名は完全にカスタマイズ可能です。これらはデフォルトのみです)。 次に、リンクを/bundes/app/assets/config/orm.phpに追加します
return array( 'relationships' => array( //.... array( 'model' => 'category' // , 'type' => 'nestedSet' ) ) );
その後、すべてが簡単です:
$fairies->children->add($sprites); $fairies->children->add($pixies); // $pixies->parent->set($fairies); // $pixies->parent->remove(); // // where('depth', 0), // // ( ) $categories = $orm->query('category')->where('depth', 0)->find(array('children'));
ところで、PHPixie自体がエンティティの削除と正しいインデックスを監視します。
誰もが新しい機能を気に入ってくれることを願っています。PHPixieを使用しない人は、最適化のアプローチが役立つと思うかもしれません。
詳細に興味がある場合、またはチャットしたい場合は、 チャットルームにアクセスしてください。