2009-11-13 4 views
11

데이터베이스에서 Tagged union을 에뮬레이트하는 가장 좋은 방법은 무엇입니까?데이터베이스에서 태그가 지정된 공용체를 에뮬레이트하는 방법은 무엇입니까?

create table t1 { 
    vehicle_id INTEGER NOT NULL REFERENCES car(id) OR motor(id) -- not valid 
    ... 
} 

vehicle_id 차 테이블 또는 모터 테이블의 ID 될 경우, 그것은 어떤을 알 것 : 나는 이런 식으로 뭔가에 대해 이야기하고있다.

(즉, 모터와 자동차 테이블이 common0에서 아무것도 가정 그럼. 중 car 또는 motor 테이블에 존재하는 값을 포함하는 vehicle_id을 허용

어떤 사람들은 이렇게 다형성 협회라는 디자인을 사용

답변

9

, 을 추가하여 t1에 주어진 행의 테이블 이름을 지정하십시오.

실제 SQL 외래 키 제약 조건을 선언 할 수 없다는 문제가 있습니다. SQL에 외래 키가없는 경우 지원되지 않습니다. 곱하기 참조 대상. 다른 문제도 있지만 참조 무결성의 부재는 이미 거래 차단 자입니다.

CREATE TABLE t1 (
    vehicle_id INTEGER NOT NULL, 
    FOREIGN KEY (vehicle_id) REFERENCES identifiable(id) 
    ... 
); 
: 다음 t1 기준이 슈퍼 테이블을

CREATE TABLE Identifiable (
id SERIAL PRIMARY KEY 
); 

:

더 나은 디자인은 모두 carmotor공통의 슈퍼의 OO 디자인에서 개념을 빌려하는 것입니다

또한 하위 유형이 상위 상위 유형을 참조하도록하십시오. 하위 유형의 기본 키는 이 아니며 자동 증가입니다. 상위 수퍼 유형은 새 ID 값을 할당하며 자식은 그 값만 참조합니다.

CREATE TABLE car (
    id INTEGER NOT NULL, 
    FOREIGN KEY (id) REFERENCES identifiable(id) 
    ... 
); 

CREATE TABLE motor (
    id INTEGER NOT NULL, 
    FOREIGN KEY (id) REFERENCES identifiable(id) 
    ... 
); 

이제 진정한 참조 무결성을 확보 할 수있을뿐만 아니라 자체 속성이있는 여러 하위 유형 테이블을 지원할 수 있습니다.


@Quassnoi 의해 답

또한 이산 아형을 적용하는 방법을 도시한다. 즉, carmotor이 상위 상위 유형 테이블의 동일한 행을 참조하지 못하게하려합니다. 이 작업을 수행 할 때 Identifiable.id에 대해 단일 열 기본 키를 사용하고 UNIQUE 키를 Identifiable.(id, type) 이상으로 선언합니다. carmotor의 외래 키는 기본 키 대신 2 열 고유 키를 참조 할 수 있습니다.

+0

'identifiable'을위한 대리 키는 질의가 선택해야하는'식별 가능한 '속성이있는 경우에만 유효합니다. '식별 가능'만이 제약 조건을 시행하는 역할을하는 경우 복합 키를 사용하면 쿼리에서 경쟁 키를 제거 할 수 있습니다. – Quassnoi

+1

필자는 '공통적 인 상위 유형'접근법을 사용하여 주요 시스템 마이그레이션/재개발 프로젝트에서 성공적으로 사용했습니다. (뉴질랜드 정부, MoE를위한 SPOT25) –

5
CREATE TABLE vehicle (type INT NOT NULL, id INT NOT NULL, 
      PRIMARY KEY (type, id) 
) 

CREATE TABLE car (type INT NOT NULL DEFAULT 1, id INT NOT NULL PRIMARY KEY, 
      CHECK(type = 1), 
      FOREIGN KEY (type, id) REFERENCES vehicle 
) 

CREATE TABLE motorcycle (type INT NOT NULL DEFAULT 2, id INT NOT NULL PRIMARY KEY, 
      CHECK(type = 2), 
      FOREIGN KEY (type, id) REFERENCES vehicle 
) 

CREATE TABLE t1 (
    ... 
    vehicle_type INT NOT NULL, 
    vehicle_id INT NOT NULL, 
    FOREIGN KEY (vehicle_type, vehicle_id) REFERENCES vehicle 
    ... 
) 
+0

그것은 할 것 : (이 가능성이 테이블 상속과는 아무 상관이 없습니다)처럼 ALL 한 Statment

당신이 정말로 행이 쿼리의 출처를 알고 싶다면, 당신은 간단한 UNION을 사용할 수 있습니다 'VEHICLE.VEHICLE_ID'를 프라이 머리 키로 정의한다면 당신은 복합 키를 참조 할 필요가 없으며 유일한 제약을 사용하는 타입 & id 컬럼을 가질 수 있습니다. –

+0

'@OMG 포니 :'이 레이아웃으로'vehicle '을 전혀 참조 할 필요가 없습니다.유형에 따라 '자동차'또는 '오토바이'로만 가입 할 수 있습니다. 여기서 '차량'은 관계를 단속하는 역할을합니다. – Quassnoi

+0

이 방법을 사용하면 '자동차'또는 '오토바이'에 해당 행이없는 '고아'차량이 없음을 보장 할 수있는 방법이 있습니까? –

3

table inheritance in PostgreSQL을 사용하여 이러한 참조를 모델링 할 수 있다고 생각합니다.

SELECT car.*, 'car' table_name 
UNION ALL 
SELECT motor.*, 'motor' table_name 
관련 문제