2012-05-26 4 views
1

저녁, MySQL의 중첩 된 세트 지리적 트리

내가 약 14,000 등 거기에 장소와 중첩 된 세트 테이블을 가지고 : 나는 세 나라 (의 Cty), 88 개 군 (공동)가

placeId  name  type  lft  rgt 
1    England  Cty   1   22878 
2    Bedfords. Co   2   259 
3    Ampthill AP   3   4 

및 각 카운티에는 아동 거주지가 있습니다 (AP, EP, Ch 및 Unk). 타입 컬럼은 깊이를 효과적으로 알려줍니다.

의 Cty = 0

공동 = 1

AP, EP, 채널 또는 UNK = 2

그러나, 나중에 내가 다른 깊이가 더 국가를 추가하기 위하여려고하고있다, 예를 들어, 미국 :

의 Cty = 0

세인트 = 1

공동 = 2

타운 /시 = 내가 원하는 나를 끌어 쿼리는 3

모든 형제 노드 및 모든 하위 노드는 사이트에서 어떤 위치가 표시되는지에 따라 1의 깊이가됩니다.

England 
**Bedfordshire 
****Ampthill 
****Arlesey 
****Aspley Guise 
*****More Towns* 
**Berkshire 
**Buckinghamshire 
***More Counties* 
Scotland 
Wales 

나는 30 이상 복용 구축하기 시작하고 쿼리 비록 : 베드 퍼 드셔 내가 싶어 선택하면

England 
**Bedfordshire 
**Berkshire 
**Buckinghamshire 
***More Counties* 
Scotland 
Wales 

을 : 잉글랜드보고있는 경우

그래서 나는 싶어 몇 초가 지나면 내가 원하는 모든 것을하지 않으므로 더 이상 진행할 필요가 없습니다.

약 100ms마다 각 깊이에 대한 쿼리를 실행하여 원하는 결과를 얻을 수 있지만 가능한 경우 단일 쿼리와 최소한의 PHP 사용을 선호합니다.

아이디어가 있으십니까?

미리 감사드립니다.

이 내가 가지고 올 수있는 최선입니다 :

(
SELECT parent.name, parent.lft, parent.rgt, 
(
CASE 
WHEN parent.type = 'Co' THEN 1 
WHEN parent.type IN('AP', 'EP', 'Ch','Unk') THEN 2 
END 
) AS depth 
FROM places AS node, places AS parent 
WHERE (parent.lft BETWEEN node.lft AND node.rgt AND (node.placeId IN(1, 7553)) AND (parent.lft BETWEEN node.lft AND node.rgt)) 
ORDER BY parent.name 
) 
UNION 
(
SELECT name, lft, rgt, 0 AS depth FROM places WHERE type = 'Cty' 
) 
ORDER BY lft 

유일한 문제는 LFT-RGT 질서를 유지하는 동안은 알파벳 순서로 그것을 밖으로 얻을 수 없다. 지금은 테이블이 이미 알파벳순으로되어 있지만 다른 장소를 추가하면 변경됩니다.

답변

1

중첩 세트로는 가능하지 않다고 생각합니다. 충분한 정보가 아닙니다. 어쩌면 공간 인덱스 나 쿼드 트리로 더 나은 행운을 누릴 수 있습니다. 쿼드 키가 있고 영국의 모든 카운티를 쿼리하려는 경우 쿼드 키의 모든 확대/축소 수준을 왼쪽에서 오른쪽으로 검색 할 수 있습니다. 따라서 쿼리 2 확대/축소 수준만으로 2 개의 깊이를 쿼리 할 수 ​​있습니다. 그러나 일반적으로 지점에서 모든 레벨을 얻습니다. 결과를 사전 식으로 정렬 할 수 있는지 확신 할 수 없지만 공간 인덱스를 사용하면 인덱스에 4 방향을 추가 할 수 있습니다. 다음은 colision detection 및 quadtrees에 대한 블로그입니다 : lab.polygonal.de/?p=202.