Postgresql : 조건부 고유 제약 조건


116

테이블의 일부에서만 열에 고유성을 적용하는 제약 조건을 추가하고 싶습니다.

ALTER TABLE stop ADD CONSTRAINT myc UNIQUE (col_a) WHERE (col_b is null);

WHERE위 의 부분은 희망찬 생각입니다.

이렇게하는 방법은 없나요? 아니면 관계형 드로잉 보드로 돌아 가야합니까?


2
일반적으로 수행됩니다. "부분 고유 색인"참조
Craig Ringer

11
@yvesonline 아니요, 그것은 규칙적인 고유 제약입니다. 포스터는 부분적인 고유 제한을 원합니다 .
Craig Ringer

답변:


186

PostgreSQL은 부분 (즉, 조건부) UNIQUE제약 조건을 정의하지 않지만 부분 고유 인덱스를 생성 할 있습니다 . PostgreSQL은 고유 한 인덱스를 사용하여 고유 한 제약 조건을 구현하므로 효과는 동일하며에 나열된 제약 조건을 볼 수 없습니다 .information_schema

CREATE UNIQUE INDEX stop_myc ON stop (col_a) WHERE (col_b is NOT null);

부분 색인을 참조하십시오 .


24
감독자! "제약"이 제약으로 표시되지 않는다는 것은 직관적이지 않지만 그럼에도 불구하고 원하는 오류를 제공합니다.ERROR: duplicate key value violates unique constraint "stop_myc"
EoghanM

7
이것은 부분적으로 고유 한 필드를 참조하는 FK를 만드는 것을 허용하지 않는다는 점에 유의할 가치가 있습니다.
ffflabs

11
이 지수 효과를 연기 할 수 없다는 점도 주목할 가치가 있습니다. 대량 업데이트를 수행해야하는 경우 제약 조건과 같은 명령문 이후 또는 지연 가능한 제약 조건과 같은 트랜잭션 이후가 아니라 모든 행 후에 고유성이 확인되므로 문제가 발생할 수 있습니다.
sage88

37

PG는 부분적인 (즉, 조건부) UNIQUE 제약 조건을 정의하지 않는다고 이미 말하고 있습니다. 또한 문서에 따르면 고유 한 제약 조건을 테이블에 추가하는 데 선호되는 방법은 ADD CONSTRAINT 고유 인덱스입니다.

고유 제한 조건을 테이블에 추가하는 선호되는 방법은 ALTER TABLE ... ADD CONSTRAINT입니다. 인덱스를 사용하여 고유 한 제약 조건을 적용하는 것은 직접 액세스해서는 안되는 구현 세부 사항으로 간주 될 수 있습니다. 그러나 고유 한 열에 대해 수동으로 인덱스를 만들 필요가 없다는 점에 유의해야합니다. 이렇게하면 자동으로 생성 된 인덱스 만 복제됩니다.

Exclusion Constraints를 사용하여 구현하는 방법이 있습니다 (이 솔루션에 대해 @dukelion에게 감사드립니다)

귀하의 경우에는 다음과 같이 보일 것입니다.

ALTER TABLE stop ADD CONSTRAINT myc EXCLUDE (col_a WITH =) WHERE (col_b IS null);

그 접근 방식에서 인덱스 방법을 정의하는 데 "사용"을 사용하지 않으므로 매우 느리거나 postgres가 기본 인덱스를 생성 할 수 있습니까? 그 방법은 표준적인 선택이지만 더 나은 선택은 아닙니다! 더 나은 선택을하기 위해서는 색인이있는 "using"절이 필요하다고 생각합니다.
Natan Medeiros

10
느리지 만 제외 솔루션의 장점은 지연 가능하다는 것입니다 (기본적으로 명령문이 끝날 때까지 지연됨). 반대로 승인 된 고유 인덱스 솔루션은 지연 될 수 없으며 행이 변경 될 때마다 확인됩니다. 따라서 업데이트 중 단계가 원자 적 업데이트 문 끝에서 위반되지 않더라도 고유 제약 조건을 위반하므로 대량 업데이트가 불가능한 경우가 많습니다.
sage88

1
이 메모는 2015 년 8 월
Raniz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.