疑似ディレクトリシステムを表すmysqlテーブルがあります。
CREATE TABLE `file_directories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`level` int(11) NOT NULL DEFAULT '1',
`created` datetime NOT NULL,
PRIMARY KEY (`name`,`id`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
ユーザーがこのシステムを閲覧しているとき、私たちの関数は列からのエントリで構成されるパスを受け取りname
ます。
したがって、first/child of first/grandchild
またはのようなものsecond/child of second/grandchild
が有効なパスであり、データベースでは次のようになります。
/----------------------------------------------------\
| id | parent_id | name | level | created |
|----|-----------|-----------------|-------|---------|
| 1 | NULL | First | 1 | ... |
| 2 | 1 | Child of First | 2 | ... |
| 3 | 2 | Grandchild | 3 | ... |
| 4 | NULL | Second | 1 | ... |
| 5 | 4 | Child of Second | 2 | ... |
| 6 | 5 | Grandchild | 3 | ... |
\----------------------------------------------------/
現在、ディレクトリの子を一覧表示する場合、私のプロセスは次のとおりです。
$path = 'first/child of first'; // demo data
$path = explode('/', $path); //array('first', 'child of first');
$level = count($path);
$name = end($path);
//query is not actually built like this, it uses the Codeigniter Active Records library
//but this is effectively the end result,
$sql = "SELECT * FROM `file_directories` WHERE `name` = '$name' AND `level` = $level";
///etc
grandchild
同じ名前で同じレベルに存在するディレクトリを処理するまでは、これは問題なく機能します。
ディレクトリ構造は、1つのディレクトリのみが同じで存在できることを強制しますが、異なる'dディレクトリが同じparent_id
に存在する可能性があります。name
name
parent_id
level
渡されるデータを変更できないため、これを行うために考えられる唯一の方法は、ルートノードから開始し、複数のクエリをループダウンして正しい子を見つけることです。
したがって、2番目の孫の場合、クエリは次のようになります。
$parent_id = NULL;
foreach($path as $seg){
$id = SQL: SELECT `id` FROM `file_directories` WHERE `name` = '$seg' AND `parent_id` = (IS NULL for root node) $parent_id;
}
//Get the actual node
$node = SQL: SELECT `*` FROM `file_directories` WHERE `id` = '$id';
しかし、それは多くのクエリなので、与えられたデータを変更せずに、ツリーをトレースするためのより良い方法はありますか?または正しいノードを選択しますか?