2009-05-16 7 views
1

현재 다양한 역량을 포함하는 분류 된 MySQL 테이블이있는 웹 사이트를 구축하고 있으며 중첩 된 세트 모델이이를 위해 최적화되어 있음을 발견했습니다. 꽤 심각한 문제가 있습니다. 중첩 된 세트 모델은 어떤 정렬도 허용하지 않으며, 우리는 실제로 그 가능성을 필요로합니다. 나는이 기능을 지원하는 등, 배열 (ID, 이름, 깊이)로 출력 데이터를 싶습니다 (정렬 모든 종류의하지 않고 있지만) :PHP : 중첩 세트의 데이터 정렬

function tree() 
{ 
    $query = 'SELECT node.id, node.name, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft'; 
    $result = mysql_query($query) or die(mysql_error()); 

    while($data = mysql_fetch_assoc($result)) 
    { 
     $returnarray[] = $data; 
    } 

    return $returnarray; 
} 

나는 기능을 시작했지만이 한 계속하는 방법을 모른다 :

function tree_sorted() 
{ 
    //Get data 
    $query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft'; 
    $result = mysql_query($query) or die(mysql_error()); 

    //Fetch gotten data 
    while($data = mysql_fetch_assoc($result)) 
    { 
     $fetched[$data['depth']][$data['id']] = array($data['name'], $data['parent']); 
    } 

    //Sort fetched data 
    foreach($fetched as $i => $row) 
    { 
     asort($row); 
     $sorted[$i] = $row; 
    } 

    //Merge sorted data (???) 
    foreach($sorted as $i => $arr) 
    { 
     foreach($arr as $x => $row) 
     { 
      $returnarray[] = array('id' => key($row), 'name' => $row[0], 'depth' => $x); 
     } 
    } 

어떤 도움을 주시면 감사하겠습니다. 중첩 된 집합에서 데이터를 정렬하는 여러 가지 방법에 대해 봤지만 아무런 결과가 없었습니다.

미리 감사드립니다.

EDIT : 지금 올바른 방법이라고 생각되는 uasort() 함수를 사용해 보았지만 문제는 여전히 남아 있습니다.

+0

사소한 점으로, 암묵적인 것보다는 SQL에 명시적인 JOIN을 권하고 싶습니다. – staticsan

답변

0

중첩 된 집합 모델을 사용한 경험으로 트래픽이 많이 발생하지 않는다면 정말 필요하지 않습니다. 정확한 계층 구조가 필요한지 잘 모르겠지만 그 앞에있는 캐시가있는 간단한 부모 - 자식 테이블이 충분하지 않은지 확인하는 것이 좋습니다. 유지 관리 및 작업이 훨씬 쉽습니다.

다시 말하지만, 이는 물론 응용 프로그램과 성능 문제가 얼마나 걱정되는지에 달려 있습니다.

+1

우리의 경우에 유용한 성능은 아닙니다.중첩 세트 모델은 쿼리의 수준 수를 제한하는 공통 상위 기술 (각 수준에는 왼쪽 조인이 필요하며이 경우 각 수준에서 수준 수는 매우 다를 수 있음)과 비교하여 무제한 수준의 범주를 지원합니다. – Ivar

0

중첩 된 설정 트리 데이터가 정의에 따라 이미 정렬되어 있으므로 데이터를 정렬하기 위해 데이터를 다른 형식 (일반적으로 플랫 한 형식)으로 변환해야하는 것처럼 들립니다. 이를 달성하는 가장 쉬운 방법은 단순히 데이터를 처리하고 이동하면서 플랫 데이터 세트를 만드는 것입니다.

SQL에 이미 몇 가지 옵션이 있습니다. Left ID로 주문하면 올바른 용어가 있으면 순서대로 트래버스됩니다. 이것은 일반적으로 목록으로 병합 할 때 의미가있는대로 사용자가 설정 트리를 나열 할 때 사람들이 원하는 것입니다. 나는 SQL에서 ORDER BY 절을 실험하고있다. 예를 들어, depth 매개 변수에 의한 정렬은 레벨 순서 트래버 설을 제공합니다. 이것을 node.name과 결합 해보십시오.

+0

고마워, 나는 그것을 시도 할 것이다. – Ivar

1

트리에 노드 집합을 정렬하고 트리에서 무제한 수준의 수준을 유지해야하는 경우 미리 정렬 된 트리 순회를 사용하는 것이 좋습니다.

구현 예는 http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/을 참조하십시오.

요점은 각 노드에 대해 왼쪽 및 오른쪽 값을 유지한다는 것입니다. 각 노드에 대해 깊이 열을 유지할 수도 있습니다.이 열은 트리의 어느 수준인지 알려줍니다.이 왼쪽 및 오른쪽 값을 사용하여 트리에서 노드를 순서대로 정렬하고 깊이 값을 사용하여 지정된 노드 만 선택할 수 있습니다 트리의 레벨 수.

이 방법의 주목할만한 단점은 노드의 구조를 변경할 때 왼쪽과 오른쪽 값을 적극적으로 유지해야한다는 것입니다.

관련 문제