문제

나는이 질문이 이미 천 번의 질문을 받았을 것 같은 느낌이 들기 때문에 대답을 받았는지 사과드립니다. 그렇다면 누군가 나를 올바른 게시물/링크를 가리킬 수 있습니까?

제가하려는 것은 내 사이트에 대한 측면 내비게이션을 구축하는 것입니다. MySQL을 사용하고 여기에 내가 사용하는 테이블의 대략적인 스케치가 있습니다.

products:
- id
- title
- description
attributes:
- product_id
- name
- value
categories:
- id
- name
products_to_categories:
- product_id
- category_id

내가하고 싶은 것은 카테고리에있을 때 사용 가능한 속성 목록을 표시하여 각 속성에 대해 하나 이상의 값을 선택할 수 있습니다. 예를 들어, Office Depot 에서이 페이지를 참조하십시오. http://www.officedepot.com/a/browse/binders/n=5+2177/

지금까지 나는 많은 조인을 사용하여 여러 속성을 필터링했습니다.

SELECT products.*, a_options.*
FROM products_to_categories AS pc, products,
attributes AS a_options,    /* list of attribute/value pairs I can continue to refine on */
attributes AS a_select1     /* first selected attribute */
attributes AS a_select2     /* second selected attribute */
...
WHERE pc.category_id = 1
AND products.id = pc.product_id
AND a_options.product_id = products.id
AND a_options.name != 'Color' AND a_options.name != 'Size'
AND a_select1.product_id = products.id
AND a_select1.name = 'Color' AND (a_select1.value = 'Blue' OR a_select1.value = 'Black')
AND a_select2.product_id = products.id
AND a_select2.name = 'Size' AND a_select2.value = '8.5 x 11'

원래 a_options 내가 사용하는 필터의 서브 세트 인 제품의 모든 속성을 반환합니다. a_select1 그리고 a_select2. 따라서 Office Depot의 바인더 예제를 사용하면 색상의 파란색 또는 검정색을 선택한 후 사용 가능한 모든 속성과 크기에 대해 "8.5 x 11"을 표시하고 싶습니다.

그런 다음 PHP 코드를 사용하여 중복을 제거하고 결과 속성을 다음과 같은 배열로 정렬합니다.

attributes[name1] = (val1, val2, val3, ...)
attributes[name2] = (val1, val2, val3, ...)

쿼리 속도를 높이거나 더 효율적으로 작성할 수있는 방법이 있습니까? 속성 테이블 (및 모든 ID 번호)의 이름과 값에 대한 설정 인덱스가 있습니다. 그러나 누군가가 몇 가지 속성을 선택하면 쿼리가 느리게 실행됩니다.

미리 도와 주셔서 감사합니다.
Sridhar

도움이 되었습니까?

해결책

"그런 다음 PHP 코드를 사용하여 복제를 제거합니다"

그렇다면 확장되지 않습니다.

내가 읽은 후 http://www.amazon.com/data-warehouse-toolkit-techniques-dimensional/dp/0471153370 나는 패싯을 롤아웃하고 필터링 메커니즘을 멈추고 있었다.

기본 아이디어는 스타 스키마를 사용하는 것입니다 ..

사실을 저장하는 사실 테이블을 만듭니다

customerid | dateregisteredid | datelastloginid
1 | 1 | 1
2 | 1 | 2

속성을 저장하는 치수 테이블에 외래 키를 사용합니다.

date_registered
Id | weekday | weeknumber | year | month | month_year | daymonth | daymonthyear
1 | Wed      | 2            | 2009 | 2   |2-2009      | 4        | 4-2-2009

그런 다음 사용하는 "패러다임"날짜는 해당 차원 테이블에서 모든 ID를 잡고

 select * from the fact table where the fact.dateregisteredid is IN( ... the ids from the date dimension table that represent your time period)

데이터의 이러한 "인덱스 뷰"는 별도의 데이터베이스에 상주해야하며, 생산 객체로 변경하면 분석 시스템에서 다시 인덱싱하기 위해 레코드해야합니다. 대형 사이트는 피크가 아닌 시간에 레코드를 통계보고 신청서에 배치 할 수 있습니다. 아키텍처가 지원한다면 항상 두 번째까지 유지하려고합니다.

RowCount Previews를 표시하는 경우 구현할 최적화 또는 캐싱도있을 수 있습니다.

기본적으로 요약하려면 데이터를 복사하고 비정상화합니다. 이 기술은 "데이터웨어 하우징"또는 OLAP (온라인 분석 처리)라는 이름으로 진행됩니다.

Oracle과 같은 상용 데이터베이스를 사용하는 더 좋은 방법이 있지만 Star Schema는 오픈 소스 관계형 데이터베이스와 시간을 가진 사람이 누구나 사용할 수있게합니다.

당신은 확실히 툴킷을 읽어야하지만 그는 당신에게 상당한 시간을 절약 할 수있는 많은 것들을 논의합니다. 업데이트 된 데이터를 다루고보고 응용 프로그램에서 감사 기록을 유지하기위한 전략과 유사합니다. 모든 문제에 대해 그는 여러 솔루션을 간략하게 설명하며, 각 솔루션은 서로 다른 상황에 적용됩니다.

쉬운 길을 가지지 않고 불필요한 조인을 사용하면 수백만 행까지 확장 할 수 있습니다.

다른 팁

정규화 된 데이터베이스 테이블을 기반으로 패싯 테이블을 생성 할 수 있습니다.
예를 들어:

> SELECT * FROM product_facet
product_id | facet_type | facet_value
1          | color      | blue
2          | color      | blue
3          | color      | green
4          | color      | yellow
1          | speed      | slow
2          | speed      | slow

그런 다음 속성 당 총계를 얻으려면이 쿼리를 간단히 수행하십시오.

SELECT facet_type, facet_value, COUNT(facet_value) as total
FROM product_facet
GROUP BY facet_type, facet_value;

결과:

facet_type | facet_value | total
color      | blue        | 2
color      | green       | 1
color      | yellow      | 1
speed      | slow        | 2

기준으로 검색 할 때 매치 제품 ID로 패싯 테이블을 선택할 수 있습니다.

SELECT facet_type, facet_value, COUNT(facet_value) as total
FROM product_facet
WHERE product_id in (SELECT product_id FROM products WHERE ... )
GROUP BY facet_type, facet_value;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top