2010-07-20 2 views
1

이것은 PostgreSQL의 실제 문제를 보여주는 장난감 예제입니다. 아래 예제는 PostgreSQL 8.4.3 서버를 사용하고 있지만 다른 버전에서도 동일한 문제가 있다고 생각됩니다. 행을 삭제하거나 테이블 스키마를 수정하지 않고PostgreSQL에서 null이 아니며 고유 한 제약 조건이있는 열을 업데이트하는 특별한 경우

 
=> select * from tmp_foo; 
foo | bar 
-----+----- 
t | f 
f | t 

:

 
=> create table tmp_foo (foo boolean not null unique, bar boolean not null unique); 
=> insert into tmp_foo (foo, bar) values (true, true), (false, false); 
=> select * from tmp_foo; 
foo | bar 
-----+----- 
t | t 
f | f 

테이블은 다음과 같이 수정할 수 있습니다 :

은 다음 표를 감안할 때? 이 :

 
=> update tmp_foo set bar = not bar; 
ERROR: duplicate key value violates unique constraint "tmp_foo_bar_key" 

이 작동하지 않습니다.

삭제가 허용하는 경우이 :

 
=> create temp table tmp_foo_2 as select * from tmp_foo; 
=> update tmp_foo_2 set bar = not bar; 
=> delete from tmp_foo; 
=> insert into tmp_foo select * from tmp_foo_2; 

작품. 이 예제에서 가장 간단한 솔루션은 아니지만 더 복잡한 예제로 쉽게 일반화 할 수 있습니다.

+0

흥미로운 문제이지만, 왜 거기에 삭제를 원하지 않는지 이해할 수 없습니다. 아주 제한된 제약 집합을 만들었습니다. 해결하려는 더 큰 문제는 무엇입니까? – Charles

답변

3

이렇게하려면 연기 가능한 고유 제한 조건이 필요합니다.

각 열에 가능한 한 많은 수의 행이 있습니다. 따라서 임의의 행을 변경하려면 일부 행이 일시적으로 고유 제한 조건을 위반해야하거나 제한 조건을 위반하지 않도록 일부 행을 삭제해야합니다. 지연 가능한 고유 제한 조건으로 인해 이전의 일시적인 위반 (트랜잭션 내부)을 수행 할 수 있습니다.

당신이 지금까지 따라하고 소리가 맞다면 질문에 대한 대답은 Postgres 버전에 달려 있습니다.

포스트그레스 최대 8.4 allows deferral of foreign key constraints. 결과는 고유 한 제한 조건을 지연시킬 수 없다는 것입니다.

Postgres 9.0 베타는 이론적으로 지연 가능한 고유 제한을 제공합니다. 나는 그것을 직접 시도하지는 않았지만,이 기능은 오랜 시간 동안 계속되어 왔기 때문에 구현하기로 결정했을 때 올바른 생각을했을 것이다.

여기에 9.0의 unique indicesSET CONSTRAINTS에 관한 관련 문서가 있습니다. 후자의 링크에서 볼 수 있듯이 고유 한 제약 조건은 9.0 설명서에서 SET CONSTRAINTS을 통해 지연에 대해 지원되는 것으로 명시 적으로 나열됩니다. 필자는 아직이 새로운 기능을 탐색하지 않았으므로 의미가 정확히 필요한 것을 보장 할 수는 없습니다. 그러나 그것은 단지 사물처럼 보인다.

+1

+1 - 9.0 새로운 기능을 가리키는 좋은 직장. – rfusca