2013-01-18 4 views
2

나는 table이라는 테이블을 가지고 있습니다. 필드에 id이라는 INT(11)이라는 식별자가 있습니다.이 식별자는 행의 식별자를 나타내며 다른 필드가 있지만이 문제와 관련이 있다고는 생각하지 않습니다.MySQL의 모든 부모 - 자식 관계

table_children이라는 테이블이 있습니다. 외부 키로 table.id을 나타내는 유형의 필드가 parent 인 필드가 있습니다. 외부 필드로 table.id을 참조하는 INT(11) 유형의 child이라는 필드가 있습니다. 이 표는 table 행에서 table 행의 부모 - 자식 관계를 설명합니다.

다음은 가능한 설정입니다.

table table_children 
id  parent child 
0  0  1 
1  1  2 
2  1  3 
3  3  4 
4 

어떻게 요청의 최소 개수에 0의 모든 자손의 id 년대를받을 수 있나요? 대답은 1, 2, 3, 4입니다.

도움 주셔서 감사합니다.

답변

2

MySQL에서는 가장 쉬운 방법은 모두 경로를 저장하여 transitive closure을 만드는 것입니다.

table_children 
parent child 
0  0 
1  1 
2  2 
3  3 
4  4 
0  1 
0  2 
0  3 
0  4 
1  2 
1  3 
1  4 
3  4 

지금 당신은 따라서를 조회 할 수 있습니다 또한

SELECT t.* 
FROM table_children c 
JOIN table t ON c.child = t.id 
WHERE c.parent = 0; 

참조 :

+0

나는 이것과 함께 갈 것이다. 이 테이블은 사전 처리되고 하나의 쿼리 만 런타임에 수행되므로 나에게 효율적으로 보인다. – Numid

0

MySQL은 재귀 쿼리와 함께 작동하도록 설계되지 않았기 때문에이를 처리하기 위해 Stored Procedures를 작성했습니다. 내 DBA의 StackExchange 게시물을 참조하십시오 : Find highest level of a hierarchical field: with vs without CTEs

나는 다음과 같은 기능

  • 데이터가 현재 설치되는 방식으로 GetParentIDByID
  • GetAncestry
  • GetFamilyTree
0

을 썼다가 모든 자손을 효율적으로 구할 수 있습니다.

SELECT child FROM table_children WHERE parent in (x, y, z); 

여기서 x, y 및 z는 모두 이전 반복에서 검색된 자식입니다. 더 이상 행이 없을 때까지 쿼리를 반복하십시오. 트리의 깊이만큼 쿼리를 수행합니다.

그러나 DB에 트리를 저장하는 방식을 변경하는 데 익숙한 경우 MPTT (Modified Pre-order Tree Traversal)라는 또 다른 방법을 사용하면 단일 쿼리로 전체 하위 트리를 가져올 수 있습니다. 업데이트는 까다 롭습니다. 당신은 여분의 복잡성이 효과적인 검색을위한 당신의 어플리케이션에 대한 좋은 절충안을 삽입 하는지를 알아야합니다.

MPTT here을 설명하는 우수 기사가 있습니다.