忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/04/26 17:29 |
PHP5.3 DBで階層構造データ管理
リレーショナルデータベースはあらゆるデータを二次元の表で表しますが、これは階層構造のデータとは非常に相性が悪いです。
社員の一覧表、といった形式には圧倒的な威力を発揮する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


2011/10/11 22:12 | Comments(0) | TrackBack() | PHP

トラックバック

トラックバックURL:

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<今週の実績 2011/10/16 | HOME | 買ったものリスト 2011/10/09>>
忍者ブログ[PR]