각 제품에 많은 매개변수가 있는 다양한 종류의 제품에 대한 제품 테이블을 디자인하는 방법

StackOverflow https://stackoverflow.com/questions/695752

문제

저는 테이블 디자인에 대한 경험이 많지 않습니다.내 목표는 아래 요구 사항을 충족하는 하나 이상의 제품 테이블을 만드는 것입니다.

  • 다양한 종류의 제품(TV, 휴대폰, PC 등)을 지원합니다.각 제품 종류에는 다음과 같은 다양한 매개변수 세트가 있습니다.

    • 휴대폰에는 색상, 크기, 무게, OS 등이 있습니다.

    • PC에는 CPU, HDD, RAM이 있습니다.

  • 매개변수 세트는 동적이어야 합니다.원하는 매개변수를 추가하거나 편집할 수 있습니다.

제품 종류별로 별도의 표를 작성하지 않고 어떻게 이러한 요구 사항을 충족할 수 있습니까?

도움이 되었습니까?

해결책

설명하는 유형 계층을 모델링하기위한이 5 가지 옵션이 있습니다.

  • 단일 테이블 상속: 모든 제품 유형에 대한 하나의 테이블, 모든 유형의 모든 속성을 저장하기에 충분한 열이 있습니다. 이것은 의미합니다 많이 열 중 대부분은 주어진 행에 널입니다.

  • 클래스 테이블 상속: 제품의 하나의 테이블, 모든 제품 유형에 공통적 인 속성을 저장합니다. 그런 다음 제품 유형 당 하나의 테이블로 해당 제품 유형에 맞는 속성을 저장합니다.

  • 콘크리트 테이블 상속: 일반적인 제품 속성에 대한 테이블이 없습니다. 대신, 제품 유형 당 하나의 테이블, 일반적인 제품 속성과 제품 별 속성을 모두 저장합니다.

  • 직렬화 된 LOB: 제품의 하나의 테이블, 모든 제품 유형에 공통적 인 속성을 저장합니다. 하나의 추가 열은 XML, Yaml, JSON 또는 다른 형식에 반 구조화 된 데이터 덩어리를 저장합니다. 이 Blob을 사용하면 각 제품 유형에 맞는 속성을 저장할 수 있습니다. 멋진 디자인 패턴을 사용하여 Facade 및 Memento와 같은이를 설명 할 수 있습니다. 그러나 당신은 SQL 내에서 쉽게 쿼리 할 수없는 속성의 덩어리가 있습니다. 전체 덩어리를 응용 프로그램으로 다시 가져 와서 정렬해야합니다.

  • 엔티티 부사장 값: 제품의 하나의 테이블과 열 대신 행에 속성을 피우는 테이블 하나. EAV는 관계형 패러다임과 관련하여 유효한 디자인은 아니지만 많은 사람들이 그것을 사용합니다. 이것은 다른 답변으로 언급 된 "속성 패턴"입니다. 다른 질문을보십시오 EAV 태그 일부 함정에 대한 stackoverflow에.

나는 프레젠테이션에서 이것에 대해 더 많이 썼습니다. 확장 가능한 데이터 모델링.


EAV에 대한 추가적인 생각 : 많은 사람들이 EAV를 선호하는 것처럼 보이지만 그렇지 않습니다. 가장 유연한 솔루션처럼 보이므로 최고입니다. 그러나 격언을 명심하십시오 탄 스타 아프. EAV의 단점 중 일부는 다음과 같습니다.

  • 칼럼을 의무적으로 만들 수있는 방법이 없습니다 ( NOT NULL).
  • SQL 데이터 유형을 사용하여 항목을 검증하는 방법이 없습니다.
  • 속성 이름이 일관되게 철자를 보장 할 방법이 없습니다.
  • 주어진 속성의 값, 예를 들어 조회 테이블에 대한 외국 키를 넣을 방법이 없습니다.
  • 기존의 표 레이아웃을 가져 오는 결과는 복잡하고 비싸다. JOIN 각 속성에 대해.

EAV가 제공하는 유연성의 정도는 다른 영역에서 희생을 요구하며, 아마도 코드를보다 전통적인 방식으로 원래 문제를 해결하는 것보다 코드를 복잡하거나 악화시키는 것일 수 있습니다.

그리고 대부분의 경우, 그 정도의 유연성을 갖는 것은 불필요합니다. 제품 유형에 대한 OP의 질문에서 제품 별 속성에 대한 제품 유형 당 테이블을 만드는 것이 훨씬 간단하므로 적어도 동일한 제품 유형의 항목에 대해 일관된 구조가 적용됩니다.

나는 EAV를 사용하는 경우에만 사용합니다 모든 행 잠재적으로 고유 한 속성 세트가 있도록 허용되어야합니다. 유한 한 제품 유형이 있으면 EAV는 과잉입니다. 클래스 테이블 상속은 나의 첫 번째 선택이 될 것입니다.


업데이트 2019 : "많은 사용자 정의 속성"문제에 대한 솔루션으로 JSON을 사용하는 사람들을 더 많이 볼수록 해당 솔루션이 적습니다. 스페셜을 사용하더라도 쿼리를 너무 복잡하게 만듭니다. JSON 기능 그들을 지원하기 위해. JSON 문서를 저장하는 데 더 많은 저장 공간이 필요하고 일반 행과 열로 저장하는 것입니다.

기본적으로 이러한 솔루션 중 어느 것도 관계형 데이터베이스에서 쉽거나 효율적이지 않습니다. "가변 속성"을 갖는 전체 아이디어는 근본적으로 관계형 이론과 상충됩니다.

그것이 내려 오는 것은 당신이 가장 나쁜 솔루션 중 하나를 선택해야한다는 것입니다. 당신의 앱. 따라서 데이터베이스 디자인을 선택하기 전에 어떻게 데이터를 쿼리 할 것인지 알아야합니다. 솔루션 중 하나가 주어진 응용 프로그램에 가장 적합 할 수 있기 때문에 "가장 좋은"솔루션을 선택할 수있는 방법은 없습니다.

다른 팁

@돌 심장

나는 EAV와 MVC를 가지고 여기에 갈 것입니다.

@빌 카빈

다음은 EAV의 단점 중 일부입니다.

No way to make a column mandatory (equivalent of NOT NULL).
No way to use SQL data types to validate entries.
No way to ensure that attribute names are spelled consistently.
No way to put a foreign key on the values of any given attribute, e.g.

조회 테이블의 경우.

여기서 언급한 모든 내용은 다음과 같습니다.

  • 데이터 유효성 검사
  • 속성 이름 철자 확인
  • 필수 열/필드
  • 종속 속성의 소멸 처리

제 생각에는 어떤 데이터베이스도 애플리케이션의 프로그래밍 언어처럼 적절한 수준에서 이러한 상호 작용과 요구 사항을 처리할 수 없기 때문에 데이터베이스에 전혀 속하지 않습니다.

제 생각에는 이런 방식으로 데이터베이스를 사용하는 것은 돌을 사용하여 못을 박는 것과 같습니다.바위를 가지고 할 수도 있지만 이런 종류의 활동을 위해 더 정확하고 특별히 설계된 망치를 사용하는 것이 좋지 않을까요?

기존의 테이블 레이아웃을 가져 오는 결과는 복잡하고 비싸다. 여러 행에서 속성을 얻으려면 각 속성에 결합해야합니다.

이 문제는 부분 데이터에 대해 몇 가지 쿼리를 수행하고 애플리케이션을 사용하여 테이블 형식 레이아웃으로 처리하면 해결될 수 있습니다.600GB의 제품 데이터가 있더라도 이 테이블의 모든 단일 행에 대한 데이터가 필요한 경우 일괄 처리할 수 있습니다.

더 나아가 쿼리 성능을 향상시키려면 다음과 같은 특정 작업을 선택할 수 있습니다.보고 또는 전역 텍스트 검색을 수행하고 필요한 데이터를 저장하고 주기적으로(예: 30분마다) 재생성되는 인덱스 테이블을 준비합니다.

추가 데이터 저장 비용은 매일 점점 더 저렴해지기 때문에 걱정할 필요조차 없습니다.

여전히 애플리케이션에서 수행되는 작업 성능에 관심이 있는 경우 언제든지 Erlang, C++, Go 언어를 사용하여 데이터를 사전 처리하고 나중에 기본 앱에서 최적화된 데이터를 추가로 처리할 수 있습니다.

내가 사용하는 경우 Class Table Inheritance 의미:

제품의 하나의 테이블, 모든 제품 유형에 공통적 인 속성을 저장합니다. 그런 다음 제품 유형 당 하나의 테이블로 해당 제품 유형에 맞는 속성을 저장합니다. -Bill Karwin

Bill Karwin의 제안 중 최고를 좋아합니다. 나는 한 가지 단점을 예측할 수 있습니다. 이것은 문제가되는 것을 막는 방법을 설명하려고 노력할 것입니다.

1 유형에 공통적 인 속성이 2, 3 등에 공통적이 될 때 어떤 비상 계획을 세워야합니까?

예를 들어 : (이것은 내 실제 문제가 아닌 예일뿐입니다)

가구를 판매하는 경우 의자, 램프, 소파, TV 등을 판매 할 수 있습니다. TV 유형은 전력 소비가있는 유일한 유형 일 수 있습니다. 그래서 나는 그것을 넣을 것이다 power_consumption 속성 tv_type_table. 그러나 우리는 또한 홈 시어터 시스템을 가지고 다니기 시작합니다. power_consumption 재산. OK 그 단지 하나의 다른 제품 이므로이 필드를 stereo_type_table 이 시점에서 아마도 가장 쉬운 것입니다. 그러나 시간이 지남에 따라 점점 더 많은 전자 제품을 운반하기 시작하면서 우리는 power_consumption 그것이 있어야 할 정도로 넓습니다 main_product_table. 지금 무엇을해야합니까?

필드를 main_product_table. 전자 장치를 통해 루프하기 위해 스크립트를 작성하고 각각의 올바른 값을 넣습니다. type_table ~로 main_product_table. 그런 다음 각 열에서 그 열을 떨어 뜨립니다 type_table.

내가 항상 같은 것을 사용하고 있다면 GetProductData 제품 정보를 가져 오기 위해 데이터베이스와 상호 작용하는 클래스; 그러면 코드의 변경 사항이 이제 리팩토링이 필요하면 해당 클래스에만 있어야합니다.

제품 ID, 추가 정보 이름, 추가 정보 값과 같은 3 개의 열이있는 제품 테이블과 별도의 ProductAdDitionInfo 테이블을 가질 수 있습니다. 많은 종류의 제품이 아닌 많은 종류의 제품이 색상을 사용하는 경우 제품 테이블의 무효 열이거나 ProductAdditionalInfo에 넣을 수 있습니다.

이 접근법은 관계형 데이터베이스의 전통적인 기술은 아니지만 실제로는 실제로 많이 사용되는 것을 보았습니다. 유연하고 성능이 우수 할 수 있습니다.

Steve Yegge는 이것을 부릅니다 속성 패턴 그리고 그것을 사용하는 것에 대한 긴 게시물을 썼습니다.

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