문제

내가 어떤 제품에 속하는 몇 가지 카테고리입니다.

각 카테고리할 수 있는 서로 다른 특성을 가지고있다.

예를 들어,

  • 카테고리 자동차 속성 색상, 력,...
  • 카테고리 애완동물 속성 체중, 나이, ...

카테고리의 수은 약 10~15.숫자의 속성에서 각각의 카테고리가 3-15.제품의 수은 매우 큰 것입니다.

주요 요구 사항에 대한 이 응용 프로그램은 매우 좋은 검색합니다.우리가 선택한 카테고리 및 입력 조건에 대한 각성이 이러한 범주에 포함됩니다.

이 있을 디자인하는 데이터베이스에 대한 이 시나리오.(SQL Server2005)

도움이 되었습니까?

해결책

고전적인 디자인 접근법은 (스타는 기본 키 열을 나타냅니다) :

Product
  ProductId*
  CategoryId: FK to Category.CategroyId
  Name

Category
  CategoryId*
  Name

Property
  PropertyId*
  Name
  Type

CategoryProperty
  CategoryId*: FK to Category.CategoryId
  PropertyId*: FK to Property.PropertyId

ProductProperty
  ProductId*: FK to Product.ProductId
  PropertyId*: FK to Property.PropertyId
  ValueAsString

문자열과 유형 변환 정보가 속성 테이블에 저장되어 모든 속성 값이 DB로 이동한다는 사실과 함께 살 수 있다면이 레이아웃은 충분합니다.

쿼리는 다음과 같이 진행됩니다.

SELECT
   Product.ProductId,
   Product.Name AS ProductName,
   Category.CategoryId,
   Category.Name AS CategoryName,
   Property.PropertyId,
   Property.Name AS PropertyName,
   Property.Type AS PropertyType,
   ProductProperty.ValueAsString
FROM
   Product 
   INNER JOIN Category         ON Category.CategoryId = Product.CategoryId
   INENR JOIN CategoryProperty ON CategoryProperty.CategoryId = Category.CategoryId
   INNER JOIN Property         ON Property.PropertyId = CategoryProperty.PropertyId
   INNER JOIN ProductProperty  ON ProductProperty.PropertyId = Property.PropertyId
                                  AND ProductProperty.ProductId = Product.ProductId
WHERE
   Product.ProductId = 1

공급 조건이 더 많을수록 (결합 적으로 사용하고) 쿼리가 더 빨라집니다. 당신이 당신의 테이블을 올바르게 인덱싱 한 경우, 즉입니다.

그대로, 솔루션은 전체 텍스트 인덱싱 상황에 이상적이지 않습니다. 제품과 관련된 모든 텍스트를보다 비정규 화 방식으로 저장하는 추가 테이블이 여기에서 도움이 될 수 있습니다. 이 테이블은 ProductProperty 테이블의 변경 사항을 듣는 트리거를 통해 업데이트해야합니다.

다른 팁

응용 프로그램 사용자 인 경우 가지다 검색하기 전에 카테고리를 선택하려면 제품을 카테고리별로 다른 데이터베이스 테이블로 분리합니다. 이 솔루션은 또한 범주 자체가 공통점이 거의 없다는 사실로 표시됩니다. 카테고리별로 분류하면 사용자가 애완 동물을 찾고있을 때 시간이 낭비되지 않기 때문에 각 검색이 훨씬 빨라집니다.

제품이 카테고리로 분할되면 각 범주의 제품의 공통 특성을 사용하여 테이블을 쉽게 만들 수 있어야합니다. 응용 프로그램의 사용자 인터페이스는 동적이어야합니다 (웹 양식을 생각하고 있습니다). 사용자가 선택할 수있는 속성이 범주를 선택할 때 변경해야한다는 점에서.

여러 카테고리에 나열하려는 제품이있는 경우이 솔루션으로 인해 테이블에 데이터가 중복됩니다. 데이터베이스를 설계 할 때 속도와 정규화 사이에는 상충 관계가 있습니다. 만약 너라면 ~하지 않다 여러 카테고리에 맞는 제품을 보유하고 있다면 이것이 가장 빠른 솔루션 (검색 속도 측면에서)이라고 생각합니다.

대부분의 사람들은 EAV (Entity-Attribute-Value) 디자인의 변형을 사용하는 것이 좋습니다. 이 디자인은 상황에 따라 과잉이며 다양한 문제가 발생합니다.

  • 속성에 대한 데이터 유형을 정의 할 수 없습니다. 정수 속성을 위해 "바나나"를 입력 할 수 있습니다.
  • 속성을 필수로 선언 할 수는 없습니다 (즉, 기존 테이블에서는 null이 아닙니다).
  • 속성에 대한 외국 키 제약 조건을 선언 할 수 없습니다.

소수의 카테고리가있는 경우 Bogdan Maxim의 답변에서 솔루션 A를 사용하는 것이 좋습니다. 즉, 카테고리 별 속성을 저장하기 위해 모든 카테고리에 공통적 인 속성을 가진 하나의 테이블 제품과 각 범주에 대해 하나의 추가 테이블을 정의하십시오.

무한한 수의 범주가 있거나 제품의 행당 다른 속성 세트를 잠재적으로 지원 해야하는 경우에만 EAV가 양호한 솔루션입니다. 그러나 EAV는 여러 정규화 규칙을 위반하기 때문에 관계형 데이터베이스를 전혀 사용하지 않습니다.

많은 유연성이 필요하다면 XML에 데이터를 저장하는 것이 좋습니다. 실제로, 당신은 RDF와 Semantic Web Framework를 조사 할 수 있습니다 참깨.

당신은 고려하고 싶을 수도 있습니다 엔티티 부사장 값 배열 유형, 각 제품을 임의의 이름/값 속성 쌍으로 "태그"할 수있는 배열 유형.

당신은 이것을 시도 할 수 있습니다. 귀하의 질문의 실제 세부 사항은 너무 확실하지 않습니다. 누군가가 당신이 조금 더 잘 번역하는 데 도움을 줄 수 있습니다.

5 테이블. 3 데이터 저장의 경우 2, 2 데이터 간 매핑을 저장하려면 2.

tProduct 
  productID
  <other product details>

tCategory
  categoryID
  <other category details>

tProperty
  propertyID
  <other property details>

tProductXCategory
  productyID
  categoryID

tCategoryXProperty
  categoryID
  propertyID

쿼리는 매핑 테이블을 사용하여 데이터에 결합해야하지만 카테고리, 속성 및 제품간에 많은 관계를 가질 수 있습니다.

저장된 절차 또는 매개 변수화 쿼리를 사용하여 검색에서 더 나은 성능을 얻으십시오.

는 경우에 유연하게하려면 귀하의 종류와 특성,을 만들어야 합니다 다음과 같은 테이블:

  • 제품:련
  • 카테고리:Int,련
  • 객실:PropertyID,Int

공유하고 싶을 때 범주 이상 mroe 보다는 하나의 제품,당신은 링크를 만들에 대한 테이블 n:m 참:

  • productCategoryPointer:ProdCatID,제품 Id,Int.

당신이 어떤 조인 쿼리에이지만,오른쪽에 인덱스,당신은 shoulb 를 쿼리할 수 있 데이터를 빠르다.

당신이 시도할 수 있습 뭔가 더 객체 지향합니다.

1.을 정의는 제품에 대한 테이블

Products(ProductID, CategoryID, <any other common properties>)

2.정의 테이블 카테고리

Categories(CategoryID, Name, Description, ..)

여기에서 당신은 많은 옵션이며 거의 모든 그들의 것입니다 휴식의 정상화 데이터베이스.

A. 솔루션

될 것입니다 maintaince 악몽을 추가해야 하는 경우 새로운 제품

A1.정의 별도의 테이블에 대한 각각의 카테고리

Cars(CarID, ProductID, ..) Pets(PetID, ProductID, ..)

A2.가입 테이블의 관계를 기반으로 사용하기 위해서는 데이터

SELECT <fields> FROM Cars INNER JOIN Products ON Cars.ProductID = Products.ProductID

B. 솔루션

정비는 악몽에 대한 다양한 유형의 속성을(즉int,varchar,etc.)

B1.을 정의 속성에 대한 테이블

CategoryProperty (CPID, Name, Type)

B2.을 정의 테이블 사이의 연결 종류와 특성

PropertyAssociation (CPID, PropertyID)

B12.정의 테이블을 개최 특성(에 대한 대안 B1B2)

Properties(CategoryID, PropertyID, Name, Type)

B3.의 각 유형을 위해 제공(int,더블,varchar,etc.) 값을 추가 테이블

PropertyValueInt(ProductID, CPID, PropertyID, Value) -int PropertyValueString(ProductID, CPID, PropertyID, Value) -문자열 PropertyValueMoney(ProductID, CPID, PropertyID, Value)

B4.모든 테이블을 적을 원하는을 제공합니다.

에 의해 이 방법을 사용하지 않는 모든 관리의 속성에 별도 표지만,유니다.기본적으로 모든 테이블을 관여하는 것을 조회 테이블이 있습니다.는 단점이기 위해서는 무료로 각 가치,당신은"케이스"에 대한 모든 가치 유형입니다.

을 마음에서는 이러한 기사()를 선택할 때는 이러한 접근한다. 이 포럼 게시물 또한 흥미롭고 어떻게든 관련 주제하더라도,그것은 대략 현지화.

수도 있습 사용 Tomalak 의 응답 추가 강력한 당신은 필요가 있다고 생각합니다.

나는 최근에 이것을해야했고 나는 3 개의 엔티티가있는 곳에 nhibernate를 사용하고있다.

제품 카테고리 옵션 옵션 카테고리

제품에는 1* 카테고리가 있습니다

제품에는 1* 옵션이 있습니다

옵션에는 1 개의 옵션 카테고리가 있습니다

이것이 설정되면 nhibernate 캐싱을 사용할 수 있습니다.

건배

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