gihyo.jp » DEVELOPER STAGE » 連載 » SQLアタマアカデミー » 第5回 SQLで木構造を扱う~入れ子集合モデル (3)入れ子集合モデルにおける更新

SQLアタマアカデミー

第5回 SQLで木構造を扱う~入れ子集合モデル (3)入れ子集合モデルにおける更新

入れ子集合モデルにおける更新

次に,木構造の更新を行う例として基本的な,ノードの挿入と削除を取り上げます。本当はもっと多くの処理を行う方法がありますが,紙幅の都合上,代表的なものだけを取り上げます。興味を持った方は,参考資料に挙げたテキストをご覧ください。

リーフを追加する

木にノードを追加するときは,リーフとして追加するのか,それとも親として追加するのかを決める必要があります。今回は,処理として簡単なリーフとして追加することを考えましょう。たとえば,部下を持たない猪狩氏(2,3)の配下に新たな部下,国見氏を追加することを考えます。

今,猪狩氏の直径は1しかないので,そのままだと部下を持てません。そこで,まずは猪狩氏の円を「広げる」ことを考えます。国見氏を追加するためには,猪狩氏の右端座標より右の円の座標を一律2だけ大きくすればよいことがわかります。これは,リスト6のUPDATE文で可能です。

リスト6 リーフの追加プロセス

--第一段階:追加するノードの席を空ける
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));

そうして猪狩氏の円の幅を広げたら,国見氏をINSERTするわけです。一般に,追加したいリーフの名前をパラメータ:child_name,親の右端座標を:parent_rgtで表せば,リーフの追加プロセスはリスト6のような二段階を踏みます。

これを今回のサンプルを使って表現すると,リスト7,図10のように具体化されます。親ノード(猪狩氏)の右端座標は3なので,:parent_rgt=3を代入します。

リスト7 今回のサンプルを使った表現

--第一段階:追加するノードの席を空ける
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));

図10 リスト7  第一段階で,猪狩氏より右のノードが右へずれ,隙間が瑞カまれる

追加後の入れ子集合を図示すると,図11のようになります。猪狩氏の円が膨らんで,それに伴い,上田氏以降の円の位置が右へ2つだけずれている様子が確認できます。

図11 リスト7実行後の入れ子集合

図11 リスト7実行後の入れ子集合

部分木の削除

今度は逆に,木からノードを削除することを考えましょう。といっても,リーフを削除することは簡単なので,部分木の削除を例にとります。つまり,部下を持つ上司を,部下ごとクビにするのです。これは,リスト8のように解雇対象の社員の左端と右端の範囲内に含まれるノードをごっそり削除することで実現できます。:fired_empは,解雇したい社員の名前です。たとえば,江崎氏を解雇すると,連座して部下の木島氏も解雇されます(リスト9,図12・13)。

リスト8 部分木の削除

DELETE FROM OrgChart
 WHERE lft BETWEEN (SELECT lft FROM OrgChart WHERE emp = :fired_emp)
               AND (SELECT rgt FROM OrgChart WHERE emp = :fired_emp);

リスト9 江崎氏を解雇(木島氏も連座)

DELETE FROM OrgChart
 WHERE lft BETWEEN (SELECT lft FROM OrgChart WHERE emp = '江崎')
               AND (SELECT rgt FROM OrgChart WHERE emp = '江崎');

図12 解雇後の組織図

emplftrgt
足立114
猪狩23
上田413
大神910
加藤1112

図13 リスト9の実行による入れ子集合の変化

図13 リスト9の実行による入れ子集合の変化

手続き型言語ならば再帰的な処理を使わねばならない木の操作も,非常に直観的に理解しやすいSQLで実現できるのが,入れ子集合モデルの大きな利点です。

おわりに

本稿で見たように,入れ子集合モデルは,RDBとSQLとのたいへん親和性の高いエレガントな方法なのですが,残念ながら欠点もあります。最大の欠点は,先にも見たように,更新時のパフォーマンスの問題です。たとえば,新しいノードを追加する場合,無関係なノードまで座標位置をずらす必要があります。木が完全な2分木で挿入位置がランダムだと仮定すると,平均で半分のノードが影響を受けます(これは順序付けられた配列に新しい要素を挿入する場合と同じです)。そのため,ノードを何百万と持つような巨大な木では,たった一つノードを追加するために,多くのノードが影響を受けることになります。もちろん,更新の間はロックもかかるため,無関係なノードへの操作も制限されてしまいます。

これを防ぐため,たとえば最初に10の倍数の座標だけを使用してあらかじめ座標の間をあけて,ノード間に「隙間」を作っておく,という逃げ手もありますが,根本的な解決策ではありません。

そこで次回では,この入れ子集合モデルの欠点を克服するための,もう一つのモデルを紹介しましょう。もう一つの,と言っても,全然無関係なものではなく,むしろ入れ子集合モデルの進化版です。実は,入れ子集合モデルはプロトタイプであり,まだ続きがあるのです。

本連載のテーマは,SQLの持つ集合論的な性格を明らかにすることでしたが,次回では,SQLが集合論と深く結びついていることを,意外な観点から確認することになるでしょう。どうぞ,お楽しみに。

参考資料
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)から入れ子集合テーブルへの変換方法など,かなり網羅的に解説したつもりです。本稿を読んで興味を持った方は,ご覧いただければ幸いです。

著者プロフィール

ミック

SI企業に勤務するDBエンジニア。主にデータウェアハウス業務に従事している。自身のサイト「リレーショナル・データベースの世界」でデータベースとSQLについての技術情報を公開している。『Web+DB Press』で「SQLアタマアカデミー」を連載中。

著書:『達人に学ぶ SQL徹底指南書』(翔泳社、2008)訳書:J.セルコ『SQLパズル 第2版』(翔泳社、2007)

SQLアタマアカデミー:サポートページ

コメント

コメントの記入

パスサポ

多数の情報処理技術者試験対策書籍の発行実績を誇る技術評論社がお届けする,資格試験合格サイト「めざせ! 情報処理試験 パスサポ」が開設されました。

ピックアップ

サクセスストーリーに続く,快適サーバー運用管理のヒント!

データの増大,煩雑な管理,システムダウン,セキュリティなど,迫りくる課題からシステム管理者の負担を軽くするポイントを解説します。

gihyo.jp インフラエンジニア情報局

ネットワークやITにかかわるあらゆる業種で必要とされるインフラエンジニアに向けた技術情報や心構え,その魅力について多角的に紹介。

テストエンジニア ステーション

いま,ITに関わるあらゆる開発業務で注目されつつあるテスト系エンジニアをターゲットにしたコンテンツサイトを展開します。

一行クイックアンケート

gihyo.jpで取り上げてほしいネタは?

※検索はページ右上の検索ボックスをご利用ください。

その他の連載

Ruby Freaks Lounge

Rubyに関わる,執筆者自身の旬なテーマを扱った,リレー形式の連載です。

これでできる! クロスブラウザJavaScript入門

JavaScriptはウェブ制作において避けては通れない重要な言語ですが,JavaScriptに苦手意識を持たれている方は少なくないようです。 その最大の原因がクロスブラウザ対応という課題であり,本連載ではクロスブラウザ対応のテクニックを詳細に解説します。

ビジネスで成功するためのシステム運用管理のポイント

システムの多様化,技術進歩に伴い,ITシステムの運用管理の必要性が年々高まっています。本連載では,システムの運用管理とは何かについて,現場のニーズと具体的な指針を押さえながらを解説します。

2010年版SEO体得講座

本連載では,いまや企業サイトの戦略の1つとして欠かすことのできないSEOについて,最新トレンドからすぐに使えるTipsまでを紹介します。

小型Linuxサーバの最高峰 OpenBlockS 600活用指南

搭載メモリの増加,CPUクロックの向上など,あらゆる面が強化された期待の新モデルOpenBlockS 600。この記事ではOpenBlockS 600の紹介から,活用するためのさまざまなノウハウを紹介していきます。

はじめMath! Javaでコンピュータ数学

プログラミング言語入門者向けに,知っていると役立つ数学的トピックスを紹介します。簡単な演習問題と解説で,即活用できる知識を目指します。

教科書には載っていない ネットワークエンジニアの実践技術

ネットワークエンジニア,インフラエンジニアのトラブル対応には,時には「教科書通りにいかない」テクニックが必要となります。資格試験では得られないこうした実践的な技術について,実例を元に紹介します。

Googleケータイ,世に現る

2008年9月,Googleが中心となって開発されている「Android」を採用した携帯電話「T-Mobile G1」が発表されました。本連載ではT-Mobile G1を中心にGoogleケータイに迫ります。

連載一覧

gihyo.jp

  • DEVELOPER STAGE
  • ADMINISTRATOR STAGE
  • WEB+DESIGN STAGE
  • LIFESTYLE STAGE
  • SCIENCE STAGE
  • NEWS & REPORT

書籍案内

  • 新刊書籍
  • 書籍ジャンル一覧
  • 書籍シリーズ一覧
  • 新刊ピックアップ
  • ロングセラー
  • 電脳会議

定期刊行物一覧

  • Software Design
  • WEB+DB PRESS
  • Web Site Expert
  • 組込みプレス

最近のコメント