문제

저는 고객을위한 EC 웹 사이트를 구축하고 있으며 프로젝트 관리자는 이상한 아이디어를 제공했으며 실제로 고객에게 판매 한 것을 구현하기 위해 고군분투하고 있습니다.

여기에 나의 주요 이슈가 있으며 시스템 설정 방법 : 제품은 카테고리 내부에 있으며 카테고리는 다른 카테고리의 어린이가 될 수 있습니다. 따라서 카테고리는 웹 사이트의 왼쪽 사이드 바에 트리로 표시됩니다.

사용자는 비 잎 카테고리를 클릭하면 레벨 1 카테고리에서 예제를 위해 제시 해야하는 경우 (레벨 2 범주에 적용) : 사용자가 비 "잎"범주를 클릭 할 수 있습니다.

big category 1
 category level ( 3 or 2 )
  product 1
  product 2
  product 3
 category level ( 3 or 2 ) 

또한 각 페이지에 5 개의 제품에 페이징과 존재가 있어야합니다. 또한 카테고리는 왼쪽 메뉴에 나타나는 동일한 방식으로 주문해야합니다 ... 내 DB 체계는 다음과 같습니다.

+-------------+    +-------------+
+ category    +    + product     +
+-------------+    +-------------+
+ category_id +    + product_id  +
+ parent_id   +    + category_id + 
+-------------+    +-------------+

제품을 주문하여 제품이 표시되도록 SQL을 코딩 해야하는 방법을 실제로 알 수는 없습니다 (제품 주문 및 카테고리에는 메뉴가 있습니다).

또한 전체 설정의 성능에 대해 우려하고 있습니다. 사용자가 비 "리프"카테고리를 선택하면 모든 어린이 카테고리를 검색하고 (id1, id2, id3)에서 큰 카테고리를 만들어야합니다. 성명서에서 잘 수행되지 않습니다.

누군가 같은 디자인/문제를 겪고 그것을 만드는 방법에 대한 조언이 있다면 감사 할 것입니다.

도움이 되었습니까?

해결책

당신은 사용할 수 있습니다 구체화 된 경로 설계. 디렉토리 경로는 구체화 된 경로의 예입니다. 즉, 일련의 조상 값이 함께 연결되어 있으며, 어떤 문자 ( "/"또는 ",", "일반적)가 분리됩니다.

따라서 카테고리가있을 수 있습니다.

+---------------------------------------------+
| cat_id | Name            | cat_path | depth |
+---------------------------------------------+
|    1   | Electronics     | 1/       |   1   |
|    2   | Digital cameras | 1/2/     |   2   |
|    3   | SLR cameras     | 1/2/3/   |   3   |
|    4   | Audio           | 1/4/     |   2   |
|    5   | Speakers        | 1/4/5/   |   3   |
|    6   | Wall Satellites | 1/4/5/6/ |   4   |
|    7   | Computers       | 1/7/     |   2   |
+---------------------------------------------+

이제 오디오 아래에있는 모든 제품을 원한다면 다음과 같은 쿼리를 수행 할 수 있습니다.

SELECT p.*, pc.*
FROM Products p JOIN Categories pc ON (p.cat_id = pc.cat_id)
JOIN Categories c ON (pc.cat_path LIKE c.cat_path||'%')
WHERE c.name = 'Audio';

예를 들어, '1/4/5/6' LIKE '1/4/%' 사실이므로 벽 위성이 포함됩니다. 오디오의 다른 하위 범주에 대해서도 동일합니다.


메뉴 렌더링에 대한 질문 : 메뉴가 렌더링되기를 원한다고 가정합니다 .- 선택한 카테고리의 모든 조상 - 선택한 카테고리의 조상의 모든 형제 자매

따라서 '스피커'를 선택하면 다음과 같습니다.

  • 전자 장치
    • 오디오
      • 스피커
    • 컴퓨터
    • 디지털 카메라

그러나 당신은 컴퓨터 나 디지털 카메라의 후손 (즉, 스피커의 "사촌")을 원하지 않습니다.

SELECT uncle.name, uncle.depth
FROM Categories chosen
JOIN Categories ancestor ON (chosen.cat_path LIKE ancestor.cat_path||'%')
JOIN Categories uncle ON (ancestor.depth = uncle.depth
  AND SUBSTRING(REVERSE(ancestor.cat_path), 3, 100) = SUBSTRING(REVERSE(uncle.cat_path), 3, 100))
WHERE chosen.name = 'Speakers'
ORDER BY uncle.depth, uncle.name;

나는 삼촌을 감지하기 위해 트릭을 사용하고 있습니다. 마지막 요소를 벗기고 나서 경로를 비교합니다. 이렇게하려면 문자열을 뒤집은 다음 첫 번째 요소. 이것은 적어도 MySQL 및 MS SQL Server에서 작동하지만 REVERSE() 표준이 아니며 다른 브랜드의 RDBM에 휴대 할 수 없습니다.

아마도 각 요소에 대해 둘 이상의 숫자를 허용해야합니다. cat_path,이 경우 서브 스트링 오프셋도 증가해야합니다.

다른 팁

성능 관점에서 이것은 나쁜 디자인입니다. 고객이 실수로 가장 큰 범주를 클릭하면 전체 인벤토리의 쿼리를 실행합니다. 이것은 아마도 용납 할 수없는 시간이 걸릴 것입니다. 웹 용어로 이것은 고객이 인내심을 잃고 라이벌 사이트를 클릭하고 다시는 사이트를 방문하지 마십시오.

물론, 조기 최적화는 모든 악의 근본이지만, 완전히 바보 같은 일을 피하는 것이 좋습니다.

또한 트리 내비게이션의 전체 아이디어를 접근 방식으로 문제를 해결할 것입니다. 고객에게 "우리가 재고를 어떻게 재고하는지 추측"하는 게임을하도록 요청하는 것보다 너무 많이 부딪칩니다. 다른 구체와는 별도로 제품은 여러 범주에 속할 수 있으므로 계층 구조에 적합하면 임의의 프로세스입니다. 최소한 제품을 여러 리프 카테고리에 할당하는 것을 지원하는 데이터 모델이 있어야 할 것입니다. (이것은 당신이 판매하는 것의 본질과 카테고리의 세분성에 달려 있습니다).

상사가 길을 가고 있다면 여전히 쿼리 성능을 향상시킬 수있는 몇 가지 옵션이 있습니다. 예를 들어, 모든 부모 카테고리가 연결된 모든 제품을 포함하는 테이블을 가질 수 있습니다 ...

cat1 product1
cat1 product2
cat1 product3
cat1 product4
cat1 cat1.1 product1
cat1 cat1.1 product2
cat1 cat1.2 product3
cat1 cat1.2 product4
cat1 cat1.1 cat1.1.1 product1
cat1 cat1.1 cat1.1.2 product2
cat1 cat1.2 cat1.2.1 product3
cat1 cat1.2 cat1.2.2 product4

트리거 또는 구체화 된보기 또는 다른 메커니즘 (데이터베이스 맛이 제공하는 것에 따라)을 통해이를 유지해야합니다. 그러나 유지 보수의 오버 헤드는 모든 고객 쿼리에 대해 제품 계층을 다시 조립하지 않아도되는 성능 이점에 비해 무시할 수 있습니다. 게다가 당신은 당신의 인벤토리에서 그 변동성이 많지 않을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top