가능

2012-04-03 2 views
0

한 적은 수의 SQL 문에서 폴더 ID는 데이터베이스 테이블을 고려 방법 : 폴더가능

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

는 'B'는 'A'내부 폴더이며, 따라서 그것은 PARENT_ID '가'의 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-> DB 문제에 대한 매우 간단한 해결책이있다

+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 함수가 모든 쿼리를 실행하는 경우 각 쿼리에 대한 요청을 보내지 만 저장 함수에서이 작업을 수행하는 경우 하나의 요청 만 필요한 모든 쿼리를 실행하는 데이터베이스 서버에 대한 하나의 요청 만 필요합니다. 결과. 여러 쿼리를 사용하는 것은 정상적인 일이지만 요청 수를 최소화해야합니다. –

+0

이렇게하면 데이터베이스 서버에 하나의 명령을 보내고 대답을 얻게 될 것이므로 db 서버는 모든 것을 내부적으로 처리 할 것입니다. –