2016-06-18 3 views
1

현재 이와 비슷한 문제가 있습니다. 아버지에 대한 정보를 저장하기위한 테이블을 만들려고합니다.여러 열 사이에 고유 제한을 적용하는 방법은 무엇입니까?

모든 아버지가 두 아들을두고 있으며 모든 아버지가 항상 두 자녀를두고 존재할 것임을 가정하십시오. Son_Table이와 상호 작용 다른 테이블이 있기 때문에

Father_Table 

father_id | son1_id | son2_id | father_text_info 
-------------------------------------------------------------- 
    13  |  8  |  11  | "some info..." 


Son_Table 

    son_id |  name  
---------------------------- 
    8  |  Moris  

단순히 Father_Table에 Son_Table 정보를 추가하지 않았습니다.

내 질문은, Father_Table에 이미있는 경우, son1_id 또는 son2_id를 Father_Table에 입력 할 수 없도록하려면 어떻게해야합니까?

CREATE TABLE father_table (
    father_id serial PRIMARY KEY, 
    son1_id integer NOT NULL, 
    son2_id integer NOT NULL, 
    FOREIGN KEY (son1_id) REFERENCES Son_Table (son_id), 
    FOREIGN KEY (son2_id) REFERENCES Son_Table (son_id), 
    UNIQUE (son1_id, son2_id), 
    UNIQUE (son2_id, son1_id), 
    UNIQUE (son1_id), 
    UNIQUE (son2_id) 
) 

중복 Son_Table ID를 가진 아래 입력이 여전히 허용 그러나 :

father_id | son1_id | son2_id | father_text_info 
-------------------------------------------------------------- 
    13  |  8  |  11  | "some info..." 
-------------------------------------------------------------- 
    14  |  11  |  8  | "other info..." 
+2

먼저 스키마가 불량하고 비정규 화되었습니다. 둘째, 총을 머리에 쓰고 그 스키마를 사용해야한다면, 트리거를 사용하십시오. – Drew

+0

'serial'은 PostgreSQL 구문입니다. [mysql] 태그를 제거하십시오. –

+1

하나의 아이디어는 논리를 뒤집고 항상 두 행을 모두 갖는 것입니다. 왕복 운동은 종종 이런 식으로 작동합니다. – Strawberry

답변

0

만큼, 여기에 중복 금지합니다 인덱스입니다 : 당신이 결합 할 경우

create extension intarray; 
create unique index idx_two_sons on father_table (sort(ARRAY[son1_id, son2_id])); 

을 그 다만 son1_id 다른에 UNIQUE 제약 조건 그냥 son2_id, 원하는대로해야합니다.

0

코멘트를 잘 있습니다

은 이미 다음과 같은 노력했다. 정상화가 그 해답입니다. PostgreSQL의 고급 기능을 사용하더라도 테이블을 정규화하지 않고 (또는 트리거를 사용하여 정규화 된 추적을 생성하지 않고) 이것을 간단하게 만들 수있는 방법을 찾을 수 없습니다.

문제는 당신이 min과 max 아들 ID를 쉽게 선택할 수 있다는 것입니다. 그러나 당신은 꽤 심각한 성능 문제없이 설정 작업에서 모든 사례를 다룰 수 없습니다.

father_to_son_id를 별도의 테이블로 분리하거나 트리거를 사용하여 테이블을 유지 관리하십시오. 그렇다면 단순한 고유 인덱스가 속임수를 쓰게됩니다. 내가 son1_id, son2_id 나쁜 디자인이라고 여기 다른 사람과 동의로

관련 문제