연결할 모델은 부분 entity–attribute–value (EAV) 모델과 비슷합니다. EAV는 매우 유연하지만 데이터 무결성이 좋지 않으며 성 가시고 일반적으로 비효율적입니다. 그것은 관계형 모델의 정신이 아닙니다. 일부 대형 전자 상거래 사이트에서 작업 한 결과 저는 이것이이 분야에서 표준 또는 좋은 데이터베이스 설계 방법이 아니라고 말할 수 있습니다.
엄청난 수의 제품 유형 (최대 10 개까지는 수백 개가 아님)이없는 경우 두 가지 일반적인 접근 방법 중 하나를 사용하여이를 처리 할 수 있습니다.
첫 번째 방법은 제품의 각기 다른 종류의 필요한 수있는 모든 속성 열이, 제품에 대한 하나의 테이블을 가지고하는 것입니다. 각 종류의 제품에 적합한 열을 사용하고 나머지는 null로 두십시오. 책, 음악 및 비디오를 판매한다고 가정하십시오.
create table Product (
id integer primary key,
name varchar(255) not null,
type char(1) not null check (type in ('B', 'M', 'V')),
number_of_pages integer, -- book only
duration_in_seconds integer, -- music and video only
classification varchar(2) check (classification in ('U', 'PG', '12', '15', '18')) -- video only
);
이렇게하면 간단하고 조인이 필요하지 않습니다. 그러나, (당신이 예를 들어, 페이지 번호가없는 책을 가질 수) 데이터에 대한 무결성을 적용하는 좋은 일을하지 않고, 당신이 제품의 몇 가지 유형 이상이있는 경우, 테이블은 매우 다루기 힘든 얻을 것이다 .
는이 같은 특정 컬럼 값을 가지고 제품의 각 유형을 필요로 테이블 수준 점검 제한 조건과 무결성 문제를 통해 석고 할 수 있습니다 조 셀코에
이
check ((case when type = 'B' then (number_of_pages is not null) else true end)))
(모자 팁 - 나는 고개 어떻게 SQL에서 논리적 의미를 수행하고 그는 매우 유사한 점검 제한 조건을 구성하기 위해이 건축과를 수행하는 예를 발견하기 위해)
는 당신은 말할 수 있습니다!
check ((case when type = 'B' then (number_of_pages is not null) else (number_of_pages is null) end)))
행에 해당 유형에 적합하지 않은 값이 있는지 확인하십시오. 해당 유형의 제품에 특정 제품 잡고 컬럼의 각 유형에 대한 모든 제품에 공통적으로 하나 개의 기본 테이블을 잡고 열, 하나 개의 보조 테이블 :
두 번째 방법은 여러 테이블을 사용하는 것입니다.따라서 :
create table Product (
id integer primary key,
type char(1) not null check (type in ('B', 'M', 'V')),
name varchar(255) not null
);
create table Book (
id integer primary key references Product,
number_of_pages integer not null
);
create table Music (
id integer primary key references Product,
duration_in_seconds integer not null
);
create table Video (
id integer primary key references Product,
duration_in_seconds integer not null,
classification varchar(2) not null check (classification in ('U', 'PG', '12', '15', '18'))
);
보조 테이블에는 주 테이블과 동일한 기본 키가 있습니다. 기본 키 열은 주 테이블에 대한 외래 키이기도합니다.
이 방법은 여전히 매우 간단하며 무결성을 강화하는 데 더 효과적입니다. 쿼리는 일반적으로 포함하지만, 조인됩니다
select
p.id,
p.name
from
Product p
join Book b on p.id = b.id
where
b.number_of_pages > 300;
무결성은 아직 완벽하지 않습니다, 기본 테이블에서 잘못된 유형의 행에 대응하는 보조 테이블에서 행을 만들 수 있습니다, 또는 행을 만들 수 있기 때문에 주 테이블의 단일 행에 해당하는 여러 보조 테이블. 모델을 더 정제하여 문제를 해결할 수 있습니다. 기본 키를 유형 열을 포함하는 복합 키로 만들면 제품의 유형이 기본 키에 임베드됩니다 (책은 ('B', 1001)과 같은 기본 키를 갖습니다). 보조 테이블에 유형 컬럼을 도입하여 외래 키가 기본 테이블을 가리킬 수 있도록하고, 유형이 올 Y 르 기가 필요한 각 보조 테이블에 점검 제한 조건을 추가 할 수 있도록해야합니다. 이처럼 :이 또한 쉽게에만 기본 키 가지게되는 권한 테이블을 조회 할 수
create table Product (
type char(1) not null check (type in ('B', 'M', 'V')),
id integer not null,
name varchar(255) not null,
primary key (type, id)
);
create table Book (
type char(1) not null check (type = 'B'),
id integer not null,
number_of_pages integer not null,
primary key (type, id),
foreign key (type, id) references Product
);
- 당신은 즉시 먼저 기본 테이블을 쿼리하지 않고도를 말합니다 제품의 종류를 알 수 있습니다.
그러나 보조 테이블에서 해당 행이 없어도 메인 테이블에 행을 만들 수 있습니다. 나는 그 문제를 해결하는 방법을 모릅니다.
기간 열이 두 테이블에 복제되는 위의 스키마에서와 같이 잠재적 인 열 중복 문제가 있습니다. 공유 열에 대한 중간 보조 테이블을 도입하여이를 해결할 수 있습니다.
create table Media (
type char(1) not null check (type in ('M', 'V')),
id integer not null,
duration_in_seconds integer not null,
primary key (type, id),
foreign key (type, id) references Product
);
create table Music (
type char(1) not null check (type = 'M'),
id integer not null,
primary key (type, id),
foreign key (type, id) references Product
);
create table Video (
type char(1) not null check (type = 'V'),
id integer not null,
classification varchar(2) not null check (classification in ('U', 'PG', '12', '15', '18')),
primary key (type, id),
foreign key (type, id) references Product
);
추가 작업이 필요하다고 생각하지 않을 수 있습니다. 그러나이 같은 상황에 대처하기 위해 두 가지 접근 방식 (단일 테이블과 보조 테이블) 혼합되어 일을하고, 제품의 일부 유사한 종류의 공유 테이블을 가진 고려해 볼 수 있습니다 무엇 :
create table Media (
type char(1) not null check (type in ('M', 'V')),
id integer not null,
duration_in_seconds integer not null,
classification varchar(2) check (classification in ('U', 'PG', '12', '15', '18')),
primary key (type, id),
foreign key (type, id) references Product,
check ((case when type = 'V' then (classification is not null) else (classification is null) end)))
);
특히 유용 할 것 응용 프로그램에서 함께 뭉친 유사한 종류의 제품이있는 경우 이 예에서 상점가가 오디오 및 비디오를 함께 제공하지만 책과 별도로 제공하는 경우이 구조는 각 유형의 미디어에 대해 별도의 보조 테이블을 갖는 것보다 훨씬 효율적인 검색을 지원할 수 있습니다.
감사합니다. 도움을 받으십시오. 그러나 이것이 내가별로 도움이되지 않을 것이라고 생각합니다. – user2455135
아, 그게 부끄러운 일입니다. 행운을 빌어 해결책을 찾는 것! –
@TomAnderson 이것은 매혹적이고 완전한 대답입니다. 엔티티 속성 값 디자인의 팬이 아닌 이유에 대한 정보를 더 제공 할 수 있습니까? 감사합니다. – mils