入れ子集合モデルにおける更新
次に、
リーフを追加する
木にノードを追加するときは、
今、
--第一段階:追加するノードの席を空ける
UPDATE OrgChart
SET lft = CASE WHEN lft > :parent_rgt
THEN lft + 2
ELSE lft END,
rgt = CASE WHEN rgt >= :parent_rgt
THEN rgt + 2
ELSE rgt END
WHERE rgt >= :parent_rgt;
--第二段階:ノードを追加する
INSERT INTO OrgChart VALUES (:child_name, :parent_rgt, (:parent_rgt + 1));
そうして猪狩氏の円の幅を広げたら、
これを今回のサンプルを使って表現すると、
--第一段階:追加するノードの席を空ける
UPDATE OrgChart
SET lft = CASE WHEN lft > 3
THEN lft + 2
ELSE lft END,
rgt = CASE WHEN rgt >= 3
THEN rgt + 2
ELSE rgt END
WHERE rgt >= 3;
--第二段階:国見氏を追加する
INSERT INTO OrgChart VALUES ('国見', 3, (3 + 1));
追加後の入れ子集合を図示すると、
![図11 リスト7実行後の入れ子集合 図11 リスト7実行後の入れ子集合](/assets/images/dev/serial/01/sql_academy2/000503/thumb/TH800_001.jpg)
部分木の削除
今度は逆に、
DELETE FROM OrgChart
WHERE lft BETWEEN (SELECT lft FROM OrgChart WHERE emp = :fired_emp)
AND (SELECT rgt FROM OrgChart WHERE emp = :fired_emp);
DELETE FROM OrgChart
WHERE lft BETWEEN (SELECT lft FROM OrgChart WHERE emp = '江崎')
AND (SELECT rgt FROM OrgChart WHERE emp = '江崎');
emp | lft | rgt |
---|---|---|
足立 | 1 | 14 |
猪狩 | 2 | 3 |
上田 | 4 | 13 |
大神 | 9 | 10 |
加藤 | 11 | 12 |
![図13 リスト9の実行による入れ子集合の変化 図13 リスト9の実行による入れ子集合の変化](/assets/images/dev/serial/01/sql_academy2/000503/thumb/TH800_002.jpg)
手続き型言語ならば再帰的な処理を使わねばならない木の操作も、
おわりに
本稿で見たように、
これを防ぐため、
そこで次回では、
本連載のテーマは、
参考資料
- Joe Celko著
『Joe Celko's Trees and Hierarchies in SQL for Smarties』 (Morgan Kaufmann Pub, 2004) - モデルの考案者自らが懇切丁寧に解説を行うのだから、
入れ子集合モデルについて知りたいならば、 本書1冊を読むだけで十分です。役に立つ技術書は世に多くあれど、 感動する技術書はそう多くありません。しかし、 残念ながら邦訳はありません。 - Stephane Faroult, Peter Robson著
『アート・ オブ・ SQL』 (オライリー・ ジャパン,2007) - 第7章で、
階層データを扱う方法を主にパフォーマンスの観点から比較検討しています。入れ子集合モデルについては 「巧妙な手法」 としつつも、 パフォーマンスについての欠点を指摘しています。しかし、 本書はもっと本質的なことも言っていて、 それは入れ子集合モデルが座標でデータを管理する以上、 結局 「ポインタベースの解決策」 であり、 RDBとSQLの理念に沿うというのは誤解だ、 という批判です。これは、 セルコにとってかなり痛いところを突いています。 - ミック著
『SQLで木と階層構造のデータを扱う (1) 』―入れ子集合モデル - 私が前掲の
『Trees and Hierarchies』 をもとに解説を行ったサイトです。検索、 更新からほかの構造 (隣接リストモデルやXML) から入れ子集合テーブルへの変換方法など、 かなり網羅的に解説したつもりです。本稿を読んで興味を持った方は、 ご覧いただければ幸いです。