2011-06-14 2 views
0

PHP/MySQL 구동 상점에서 중첩 된 집합 쿼리로 정말 어려움을 겪고 있습니다. 예를 들어 전자 부품을 사용하겠습니다.MySQL 중첩 집합 검색

범주는 중첩 된 집합 모델 (왼쪽, 오른쪽 및 깊이)로 저장됩니다. 고객이 매장을 통해 탐색으로

, 그들은

는 고객이 소니의 모든 제품을보고있는 말을하자 등 브랜드, 카테고리, 가격 범위에 의해 제품 목록을 필터링 할 수 있습니다. Sony는 Computing, Television, Audio 및 Hosuehold Appliances의 제품을 보유하게됩니다.

하지만 소니 제품은 (그러나이 될 수있다), 그들은 같은 그 주요 범주의 하위 범주에 저장되어 그 범주에 저장되지 않습니다 : 고객이 소니를 선택한 후

Televisions > LCD > Widescreen 
Televisions > CRT 
Computing > Optical Drives > DVD-RW 
Computing > Input Devices > Wireless > Keyboards 
Audio > Portable > MP3 
Household Appliances 

, 나는 그 카테고리로 좁힐 수있는 옵션을 갖고 싶어, 그래서 그들은 처음에 이러한 선택했을 :

Televisions 
Computing 
Audio 
Household Appliances 

을하지만 난 단지 특정 범주의 목록을 다시 가져 오는 쿼리를 수행 할 수 있습니다

LCD 
CRT 

사람이 바람직 가능한 한 빨리 정보를 반환, 이것 좀 도와 줄래과 :

Widescreen 
CRT 
DVD-RW 
Keyboards 
MP3 
Household Appliances 

나는 고객이 텔레비전을 선택하면 다음, 그들은 선택을 얻을 것, 보여 주 범주가 필요합니다 최소 재귀 (따라서 중첩 된 집합을 처음 사용하는 경우) 또는 너무 많은 쿼리를 사용하면 매우 감사 할 것입니다. 이 데이터베이스의 구조에 도움이된다면 여기

내가 하위 범주의 목록을 얻을하는 데 사용하는 쿼리입니다 :

select  c.categories_id, cd.categories_name, c.parent_id, c.lft, c.rgt, c.dpth 
from  categories c 
inner join categories_description cd on cd.categories_id = c.categories_id 
inner join products_to_categories p2c on p2c.categories_id = c.categories_id 
inner join products p on p.products_id = p2c.products_id 
where  cd.language_id='1' 
and   c.lft between 3489 and 3670 
and   c.categories_status = '1' 
group by c.categories_id 
order by sort_order, cd.categories_name 

데이터베이스가 원래 adjacancy 모델 구조이었다, 각 카테고리 ID는 또한 부모가 ID가 저장되어 있으면 모든 작업이 간단 해집니다.

감사합니다.

+0

. 나는 개인적으로 옵션 2 좋아하고 문제가 발견 적이 없다.

을 자신을 주문할 수 있지만, 그것은 매우 느립니다 어떤 방법으로 색인을 생성하거나 작동 방식을 변경합니까? – Paul

+0

SELECT \t \t cd. *, ancestor.* \t \t'fec_categories' 아이 FROM 는 ancestor.'lft' 간의 child.'lft' ON \t \t'fec_categories' 조상 가입하고 ancestor.'rgt' 는 ancestor.'categories_id' = ON \t \t'fec_categories_description' CD를 가입 cd.'categories_id' 는 p.products_id = p2c.products_id \t \t p.'manufacturers_id' = 6 AND \t \t \t \t 자식 fec_products 피 가입 child.categories_id = p2c.categories_id 에 \t \t fec_products_to_categories의 P2C 가입. '케이트 gories_status' = 1 AND \t \t ancestor.'categories_status' = 1 AND \t \t cd.'language_id' = 1 AND \t ancestor.' BY ancestor.'categories_id' ORDER BY ancestor.'dpth' = 1 GROUP lft' – Paul

+0

필자는 결국이 문제를 포기하고 Bill Karwin의 전이 폐쇄 테이블 방법으로 넘어갔습니다. 이것은 우리 요구 사항에 훨씬 더 적합합니다. – Paul

답변

0

귀하의 의견에서 다른 것을 시도했지만 어쨌든 대답 할 것이라고 생각했습니다.

당신이 발견 한대로 nested set 모델은 노드를 검색하는 데 뛰어나며 빠르고 효율적으로 리프를 나타냅니다. 단 하나의 gotchya은 삽입 후 목록을 주문하기가 어렵다는 것을 알았습니다.

나는 이것을 클라이언트 측에서 (어려운) 순서로 정렬 한 다음 캐싱하거나 b) 노드/리프를 삽입하여 자동으로 정렬되도록합니다 (또는 위/아래 링크를 사용하기도합니다). 그래서 삽입이 일어난 후에 관리자는 내가 가지가 작동하도록 관리해야