可能

2012-04-03 7 views
0

としていくつかのSQL文のフォルダIDは、データベーステーブルを考えてみましょう行き方:フォルダ可能

 
folders 
id parent_id name 
1 0   a 
2 1   b 
3 2   c 

は、「b」は「A」内のフォルダであり、したがって、それはPARENT_IDが「A」のIDであるのです。
parent_idが0のフォルダは、単にルートフォルダにあることを意味します。

私は私が私が興味パスのIDを取得することができますPHPの再帰関数を書いた

たとえば:。

echo get_folder_id('a/b/c'); // 3 (3 SQL queries) 
echo get_folder_id('a'); // 1 (1 SQL query) 
echo get_folder_id('a/b'); // 2 (2 SQL queries) 
echo get_folder_id('a/c'); // false (2 SQL queries) 

問題:各フォルダの中にパス、私はDBサーバーにSQLクエリを作成する必要がありました。

質問:パスが「a/b/c」の場合、クエリの数を減らす方法はありますか?

ここに参考になる私の現在の解決策があります。

function get_folder_id($path, $parent_id=0) { 
    $path = explode('/', $path); 
    $id = 0; 

    //if there's only 1 folder in the path, query the database for the ID 
    if (count($path) == 1) { 
     $rs = $this->db->select('id') 
       ->from('folders') 
       ->where('name', $path[0]) 
       ->where('parent_id', $parent_id) 
       ->limit(1) 
       ->get(); 

     if ($rs->num_rows() == 0) return FALSE; 

     $result = $rs->row_array(); 
     return $result['id']; 
    } 

    foreach($path AS $i=>$p) { 
     if ($i==0 && $p=='') continue; //if a path starts with/move on to the next item 
     $id = $this->get_folder_id($p, $id); 
    } 

    return $id; 
} 

注:私はCodeIgniterフレームワークを使用していますが、これは私の質問には関係ありません。ちょうど私がの$ this - を使用し、なぜ人々は> get_folder_id()との不思議ための$ this - >デシベルあなたの問題のために非常に簡単な解決策はあり

+0

フォルダの最大深度はどのくらいですか? – safarov

+0

最大の深さはありません。これは、あなたが望むだけフォルダを入れ子にすることができるように設計されています。 – wyred

+0

パス内の各フォルダに各IDが必要ですか? – cloakedninjas

答えて

0

ちょうど私が思いついたのは、同じテーブルに一連のLEFT JOINを使用することでした。

SELECT tb3.id FROM folders AS tb1 
LEFT JOIN folders AS tb2 ON tb2.parent_id=tb1.id 
LEFT JOIN folders AS tb3 ON tb3.parent_id=tb2.id 
WHERE tb1.name='a' AND tb2.name='b' AND tb3.name='c' 
LIMIT 1 

パス内のフォルダ数に基づいて、上記のSQLを動的に生成できます。 これが完璧な解決策であるかどうかはわかりませんが、今は意図したとおりに機能しています。

これが良いアイデアかどうかについてのフィードバックは非常に高く評価されています!

$path = 'a/b/c'; 
$path = explode('/', $path); 

$sql = "SELECT tb".count($path).".id FROM folders AS tb1"; 
for($x=1, $max = count($path); $x<=$max; $x++) { 
    $sql .= " LEFT JOIN folders AS tb".($i+2); 
    $sql .= " ON tb".($i+2).".parent_id = tb"($i+1).".id"; 
} 

$sql .= " WHERE 1"; 

foreach($path AS $x => $p) { 
    $sql .= " AND tb".($x=1).".name='".$p."'"; 
} 

$sql .= " LIMIT 1"; 
0

データベースの再帰的なストアド・ファンクションを作成してからそれを呼び出しますPHP。 PHPでこれを実装すると、PHPから多くのクエリを送信する必要があるため、これはDBの機能性を正確に反映するはずです。

+0

DBで再帰関数を作成しても、それでも "複数のクエリ"が実行されますか?私はストアド・ファンクションに慣れていません。 – wyred

+0

複数のクエリを実行しますが、ここで問題はありません。問題は、PHP関数がすべてのクエリを実行する場合、クエリごとにリクエストを送信することですが、ストアド関数でこれを行う場合は、データベースサーバに対して1つのリクエストだけが必要です。結果。複数のクエリを使用するのは普通のことですが、リクエスト数を最小限に抑える必要があります。 –

+0

このようにして、データベースサーバに1つのコマンドを送信し、回答を得ると、dbサーバはすべてを内部的に処理します。 –

関連する問題