2017-04-11 2 views
0

나는 다음과 같은 테이블이 있습니다모든 열이 없지만 다른 외래 키를 통해 가져올 수있는 복합 기본 키를 참조하는 외래 키를 추가하는 방법은 무엇입니까?

create table AAA 
(
    AAA_ID NUMBER 
); 

alter table AAA 
    add constraint AAA_PK 
    primary key (AAA_ID); 

create table BBB 
(
    BBB_ID NUMBER, 
    AAA_ID NUMBER 
); 

alter table BBB 
    add constraint BBB_PK 
    primary key (BBB_ID, AAA_ID); --IMPORTANT 

alter table BBB 
    add constraint BBB_FK_01 
    foreign key (AAA_ID) 
    references AAA (AAA_ID); 

create table CCC 
(
    CCC_ID NUMBER, 
    AAA_ID NUMBER 
); 

alter table CCC 
    add constraint CCC_PK 
    primary key (CCC_ID); --IMPORTANT 

alter table CCC 
    add constraint CCC_FK_01 
    foreign key (AAA_ID) 
    references AAA (AAA_ID); 

create table CCC_BBB 
(
    CCC_ID NUMBER, 
    CCC_BBB_ID NUMBER, 
    BBB_ID NUMBER 
); 

alter table CCC_BBB 
    add constraint CCC_BBB_PK 
    primary key (CCC_ID, CCC_BBB_ID); 

alter table CCC_BBB 
    add constraint CCC_BBB_FK_01 
    foreign key (CCC_ID) 
    references CCC (CCC_ID); 

내가 CCC_BBBBBB를 참조에 외래 키 제약 조건을 추가 할 수 있습니다. BBB_IDCCC_BBB에 직접 존재하지만, AAA_ID은 없습니다. 그러나, AAA_ID은 에 있으며, 이는 CCC_BBB_FK_01으로 참조됩니다. SQL에서이 제약 조건을 표현할 수 있습니까?

표준 호환 솔루션을 선호하지만 오라클 전용 솔루션도 환영합니다.

편집. 실제 문제가 무엇인지 명확히하라는 질문을 받았으므로이 질문은 제 시도입니다. 차라리 실제 문제 영역을 논의하지 않겠습니다.

AAA는 프로세스입니다. BBB는 프로세스 단계입니다. 여러 프로세스는 이름이 비슷하지만 단계가 다르므로 테이블에 복합 키가 있습니다. CCC는 프로세스 인스턴스입니다. ID는 고유하므로 테이블에 복합 PK가 없습니다. CCC_BBB는 특정 인스턴스에서 수행 된 단계 목록입니다.

프로세스 인스턴스에 대한 단계 목록에 해당 프로세스에 허용되는 단계 만 포함되어 있는지 확인해야합니다.

+2

나는 당신이 묘사 한 것이 가능하다고 믿지 않습니다. –

+0

당신의 이론적 인 본보기가 완전한 의미는 아닙니다. – jarlh

+0

모든 테이블을 만든 후에 모든 alter 명령을 실행할 수있는 편도 –

답변

1

귀하의 문제는 복합 키가 하프 하트로만 적용된 것으로 보입니다.

먼저 기술 비 합성 키부터 시작해 보겠습니다. 가독성을 높이기 위해 테이블과 컬럼 이름의 이름을 약간 변경했습니다. 기본 키는 굵게 표시됩니다.

  • A (A_ID, COL1, COL2, ...)
  • AB (AB_ID, A_ID, COL1, COL2, ...)
  • AC (AC_ID, A_ID, COL1, COL2, ...)
  • ABC (ABC_ID, AC_ID, AB_ID, COL1, COL2, ...)

H 우리는 당신이 묘사하는 상황을 가지고 있습니다 : AC와 AB는 A와 B의 자식이고 ABC는 AB와 AC의 자식입니다. 그러나 DBMS는 BC가 B와 C를 모두 포함하고 있다는 것을 보장 할 수 없습니다. 둘 다 A에 속합니다. 순수 ID 기반 데이터베이스 설계의 알려진 단점; 테이블의 계층 구조에 대한 일관성을 보장하지 못합니다. (자연 키가 매우 일반적이지만, 너무, 기술 ID가 작동) 복합 키 이제

같은 :

  • A (A_ID, COL1, COL2를, ...)
  • AB (A_ID, B_ID, COL1, COL2, ...)
  • AC (A_ID, C_ID, COL1, COL2, ...)
  • ABC (A_ID, B_ID, C_ID, col1, col2, ...)

완전한 상위 키는 항상 기본 키의 일부이므로 일관성이 보장됩니다.

당신이하고있는 일은 혼합입니다. 마지막 테이블에는 복합 키를 적용하지만 그렇지 않은 모든 부모 테이블에는 복합 키를 적용하고 있으므로 너무 늦었습니다. 비 합성 ID 개념을 사용하여 일관성 문제가 발생했습니다.

  • A (A_ID, COL1, COL2, ...)
  • AB (AB_ID, A_ID, COL1, COL2, ...)
  • AC (AC_ID, A_ID, COL1, COL2, ...)
  • ABC (AC_ID, ACSUB_ID, AB_ID, COL1, COL2, ...)
+0

AAA_ID/A_ID를 CCC/AC 테이블 PK에 추가하지 않으면 짧은 대답은 '아니오'입니다. 불필요한 것이지만? – Alexey

+0

대답은 : 합성 ID가 아닌 ID를 사용하는 경우 원하는 일관성 보장없이 이루어집니다. 당신이 복합 ID를 사용한다면 그것을 얻습니다. 그렇지만 일관성을 유지하십시오 : BBB와 CCC 복합 키를주고 두 키의 CCC_BBB 키를 작성하십시오. 이것에 대해 불필요한 것은 없습니다. –

+0

물론 혼란 스러울 수 있습니다. CCC_BBB에 AAA_ID를 중복해서주고, CCC_BBB의 외래 키에 사용할 수있는 BBB (BBB_ID, AAA_ID)에 (불필요한) 고유 제약 조건을 추가합니다. 나는 이것을 권장하지 않을 것이다. –

0

Y OU는 두 개의 테이블을 조인하는 구체화 된 뷰를 사용하고이에 외래 키를 추가 할 수 있습니다

CREATE MATERIALIZED VIEW LOG ON CCC_BBB 
    WITH SEQUENCE, ROWID(CCC_ID,CCC_BBB_ID,BBB_ID) 
    INCLUDING NEW VALUES; 

CREATE MATERIALIZED VIEW CCC_BBB_MV 
    BUILD IMMEDIATE 
    REFRESH FAST ON COMMIT 
    AS SELECT CCC_ID, 
      CCC_BBB_ID, 
      BBB_ID, 
      AAA_ID 
     FROM CCC_BBB b 
      INNER JOIN 
      CCC c 
      ON (b.CCC_ID = c.CCC_ID); 

ALTER TABLE CCC_BBB_MV ADD CONSTRAINT ccc_bbb_mv__fk 
    FOREIGN KEY (AAA_ID, BBB_ID) REFERENCES BBB (AAA_ID, BBB_ID); 

(코드 위 이 검증되지 않은이지만 솔루션의 설명을해야한다)

하여 작동 할 수 있지만 , 약간의 해킹입니다. 따라서 AAA_IDCCC_BBB 테이블에 추가하기 위해 더 적은 저장 공간을 사용하게됩니다.

관련 문제