2010-04-26 4 views
4

제품 유형별로 매우 다른 속성을 가질 수있는 제품 데이터베이스를 디자인하고 있지만 속성은 각 유형마다 고정되어 있으며 유형은 전혀 관리 할 수 ​​없습니다. 예 :데이터베이스 디자인 : 다른 속성을 가진 객체

잡지 : 제목, ISSUE_NUMBER는, 페이지, 복사, close_date는
WEB_SITE 출시일 : 이름을, 대역폭, 명중, date_from, 내가 이노을 사용하고 데이터베이스 무결성을 적용 할 DATE_TO

엔진이 허용하는 한 많은 것. 이 문제를 해결하기위한 권장 방법은 무엇입니까? 글쎄, 난 ...

product_type 
============ 

product_type_id INT 
product_type_name VARCHAR 

product 
======= 

product_id INT 
product_name VARCHAR 
product_type_id INT -> Foreign key to product_type.product_type_id 
valid_since DATETIME 
valid_to DATETIME 

magazine 
======== 

magazine_id INT 
title VARCHAR 
product_id INT -> Foreign key to product.product_id 
issue_number INT 
pages INT 
copies INT 
close_date DATETIME 
release_date DATETIME 

web_site 
======== 

web_site_id INT 
name VARCHAR 
product_id INT -> Foreign key to product.product_id 
bandwidth INT 
hits INT 
date_from DATETIME 
date_to DATETIME 

이 직렬 처리 할 수있는 제품 삭제하지만 :

나는 테이블 100 열이 있고 대부분의 값은 내가 이런 식으로 뭔가에 대해 생각 때문에 NULL입니다 그 디자인을 싫어 완전히 확신하지 못했습니다 ...

답변

5

이것은 관계형 테이블의 임피던스 불일치에 대한 고전적인 OO 설계입니다. 설명 된 테이블 디자인을 '서브 클래스 당 테이블'이라고합니다.

  1. 표 콘크리트 클래스
  2. 표 계층 당
  3. 표 서브 클래스

디자인 당 당 : 가장 일반적인 세 ​​가지 디자인은 객체가 실제로 응용 프로그램에서 어떻게 보이는지에 비해 모든 타협하다 당신은 싫어한다 - "테이블이 100 개의 열을 갖고 대부분의 값이 NULL 인"-은 2. 전체 특성화 계층 구조를 저장하는 하나의 테이블. 앱에 새로운 하위 클래스가 필요한 경우 열을 추가해야하는 등 모든 종류의 이유로 유연성이 가장 낮습니다. 설명하는 디자인은 product_type에 값으로 설명 된 새 하위 클래스 테이블을 추가하여 확장 할 수 있기 때문에 훨씬 쉽게 변경됩니다.

나머지 옵션 - 1. 구체적인 클래스 당 테이블 -은 각 전문화 테이블의 모든 공통 필드를 구현하는 데 필요한 중복으로 인해 일반적으로 바람직하지 않습니다. 장점은 조인을 수행 할 필요가 없으며 서브 클래스 테이블이 매우 큰 시스템의 다른 db 인스턴스에있을 수도 있다는 것입니다.

설명하신 디자인이 완벽하게 실행 가능합니다. 아래의 변형은 ORM 도구를 사용하여 CRUD 작업을 수행하는 방법을 보여줍니다. 각 하위 클래스 테이블의 ID가 계층 구조의 상위 테이블에 대한 FK 값인지 확인합니다. 좋은 ORM은 product.id 및 product.product_type_id의 discriminator 값의 값만을 기반으로 올바른 하위 클래스 테이블 CRUD를 자동으로 관리합니다. ORM을 사용하든 안하지 않든간에 hibernate는 자신이 만든 디자인 결정을보기 위해서만 하이버 네이트의 조인 된 서브 클래스 문서를 살펴 본다.

product 
======= 

id INT 
product_name VARCHAR 
product_type_id INT -> Foreign key to product_type.product_type_id 
valid_since DATETIME 
valid_to DATETIME 

magazine 
======== 

id INT -> Foreign key to product.product_id 
title VARCHAR 
.. 

web_site 
======== 

id INT -> Foreign key to product.product_id INT 
name VARCHAR 
.. 
+0

세 가지 가능한 디자인에 대한 좋은 개관, 감사합니다. 모든 답변이 훌륭했지만 한 가지만 선택할 수 있습니다 : <:-)' –

2

"제품"과 "재고 관리 단위"(SKU)의 차이점을 고려해야 할 경우가 대부분입니다. 25 단위 상자 (특정 특정 종류의)의 종이 클립은 50 단위 상자와 동일한 "제품"입니까? 상점 또는 어떤 종류의 재고 시스템의 관점에서, 구별은 중요합니다. 경우에 따라 패키징에있는 동일한 단순한 차이점을 제외하면 동일한 기본 제품의 동일한 양을 추적 할 수있는 고유 한 SKU를 제공 할 수 있습니다.

응용 프로그램과 관련하여이 문제를 추적 할 위치를 결정해야합니다 (사용자가하는 것처럼 제품을 배치하고 다른 테이블의 SKU 용도로 포장 처리하는 것이 좋을 수 있습니다. 예를 들어 약간의 오버 헤드가있는 일부 앱의 경우에도 마찬가지입니다.

1

실제로 이것은 고전적인 RDBMS에서 일종의 객체 지향 디자인을 "시행"하는 표준 방법입니다.

세부 정보가 하위 테이블로 이동하는 동안 모든 '공통'속성이 마스터 테이블 (예 : 제품 테이블 수준에서 유지되는 경우 쉽게 주 테이블의 일부가 될 수 있음)에 있습니다.

이론상으로 하위 잡지가있는 경우 (예 : 잡지는 일간 신문과 4 색 정기 간행물에 하위 유형이있을 수 있으며 유효 기간에 대한 정기 간행물이있는 정기 간행물 일 수 있습니다) 하나 이상의 하위 레벨을 추가 할 수 있습니다 ...

이것은 꽤 일반적인 (입증 된) 디자인입니다. 유일한 문제는 대부분의 작업에서 마스터 테이블이 항상 하위 테이블과 조인된다는 것입니다. 항목이 많으면 성능에 영향을 미칠 수 있습니다.

한편, 항목 삭제와 같은 일반적인 작업 (모든 논리적 삭제, 기본 테이블에서 "true"로 플래그 설정)은 모든 종류의 하위 유형에 대해 한 번 수행됩니다.

어쨌든 간다. 그리고 아마도 "객체 지향 RDBMS 매핑"또는 somesuch a complete discussion에 대한 주위에 Google.