リレーショナルデータベースはあらゆるデータを二次元の表で表しますが、これは階層構造のデータとは非常に相性が悪いです。
社員の一覧表、といった形式には圧倒的な威力を発揮するDBですが、そこに上司や部下といった要素が入ってくると途端に見辛くなってしまいます。
データを取得するときも自己結合や外部結合を駆使したアクロバティックなSQL文を書かねばなりません。
SQLで階層構造を扱う方法も色々編み出されていますが、PHPにおいてはPear::DB_NestedSetを使用することでそこらへんを隠蔽し階層構造として扱うことができます。
http://www.geocities.jp/mickindex/database/db_tree_ns.html
http://pear.php.net/package/DB_NestedSet
DB_NestedSet 1.4.0RC1 (beta)
ということらしいのですが使い方がよくわかりません。
とりあえずマニュアルの例「ルートおよびサブノードの作成」を試してみる。
http://pear.php.net/manual/ja/package.DB_NestedSet.php
Fatal error: DB Error: no such table in C:\htdocs\dbNestedSet.php on line 873
あぁ?
実は使用前にnested_setテーブルおよびnested_set_locksテーブルを作成しないといけないのですが、そのことについて全く日本語情報がありません。
どんだけ使われてないんだDB_NestedSet。
英語情報が見つかったのでさくっとコピペでテーブルを作成。
http://trac.seagullproject.org/wiki/Howto/Navigation/HtmlMenu
http://www.php-resource.de/forum/showthread/t-49204.html
子ノードに孫ノードを付け足したい場合も、
む。
普通は
実は$child2は単なる数値(nested_set.id)で、SimpleXMLみたいな再帰構造にはなっていません。
http://jp.php.net/manual/ja/book.simplexml.php
おかげでメソッド再帰呼び出しで値を投入しようか、なんてときに微妙。
ちなみにこのサンプル、$DatabasePointerは全く意味がないので削除してかまいません。
あと実際に本気で使用するのであれば、
社員の一覧表、といった形式には圧倒的な威力を発揮するDBですが、そこに上司や部下といった要素が入ってくると途端に見辛くなってしまいます。
データを取得するときも自己結合や外部結合を駆使したアクロバティックなSQL文を書かねばなりません。
SQLで階層構造を扱う方法も色々編み出されていますが、PHPにおいてはPear::DB_NestedSetを使用することでそこらへんを隠蔽し階層構造として扱うことができます。
http://www.geocities.jp/mickindex/database/db_tree_ns.html
http://pear.php.net/package/DB_NestedSet
DB_NestedSet 1.4.0RC1 (beta)
ということらしいのですが使い方がよくわかりません。
とりあえずマニュアルの例「ルートおよびサブノードの作成」を試してみる。
http://pear.php.net/manual/ja/package.DB_NestedSet.php
Fatal error: DB Error: no such table in C:\htdocs\dbNestedSet.php on line 873
あぁ?
実は使用前にnested_setテーブルおよびnested_set_locksテーブルを作成しないといけないのですが、そのことについて全く日本語情報がありません。
どんだけ使われてないんだDB_NestedSet。
英語情報が見つかったのでさくっとコピペでテーブルを作成。
http://trac.seagullproject.org/wiki/Howto/Navigation/HtmlMenu
http://www.php-resource.de/forum/showthread/t-49204.html
CREATE TABLE `nested_set` ( `id` int(10) unsigned NOT NULL default '0', `parent_id` int(10) unsigned NOT NULL default '0', `order_num` tinyint(4) unsigned NOT NULL default '0', `level` int(10) unsigned NOT NULL default '0', `left_id` int(10) unsigned NOT NULL default '0', `right_id` int(10) unsigned NOT NULL default '0', `name` varchar(60) NOT NULL default '', PRIMARY KEY (`id`), KEY `right` (`right_id`), KEY `left` (`left_id`), KEY `order` (`order_num`), KEY `level` (`level`), KEY `parent_id` (`parent_id`), KEY `right_left` (`id`,`parent_id`,`left_id`,`right_id`) ) TYPE=MyISAM; CREATE TABLE `nested_set_locks` ( `lockID` char(32) NOT NULL default '', `lockTable` char(32) NOT NULL default '', `lockStamp` int(11) NOT NULL default '0', PRIMARY KEY (`lockID`,`lockTable`) ) TYPE=MyISAM COMMENT='Table locks for comments';その後サンプルを実行すると親ノード「root 1」に子ノード「node 1.1」「node 1.2」を持つ簡単なツリーができあがりました。
root 1 |
node 1.1 |
node 1.2 |
子ノードに孫ノードを付け足したい場合も、
$child2 = $nestedSet->createSubNode($parent, array('name' =>'node 1.2')); $nestedSet->createSubNode($child2, array('name' =>'node 2.1'));とcreateSubNode()に引数を渡すだけで簡単に追加することができます。
む。
普通は
$child2->createSubNode(array('name' =>'node 2.1'));とかじゃねーの?
実は$child2は単なる数値(nested_set.id)で、SimpleXMLみたいな再帰構造にはなっていません。
http://jp.php.net/manual/ja/book.simplexml.php
おかげでメソッド再帰呼び出しで値を投入しようか、なんてときに微妙。
ちなみにこのサンプル、$DatabasePointerは全く意味がないので削除してかまいません。
あと実際に本気で使用するのであれば、
$nestedSet =& DB_NestedSet::factory('MDB2', $dsn, $params);とMDB2を使用するようにした方がよいでしょう。
PR
トラックバック
トラックバックURL: