ioseph=# drop table if exists t;
알림: "t" 테이블 없음, 무시함
DROP TABLE
-- 테이블 만들고
ioseph=# create table t (a int);
CREATE TABLE
-- unique 제약 조건 추가하고,
ioseph=# alter table t add unique (a);
ALTER TABLE
ioseph=# insert into t values (1);
INSERT 0 1
-- unique 제약 조건이 잘 작동하는지 확인하고,
ioseph=# insert into t values (1);
오류: 중복된 키 값이 "t_a_key" 고유 제약 조건을 위반함
상세정보: (a)=(1) 키가 이미 있습니다.
-- unique 지우고,
ioseph=# alter table t drop constraint t_a_key;
ALTER TABLE
-- 이번에는 exclude 제약 조건을 만들고,
ioseph=# alter table t add exclude (a with =);
ALTER TABLE
-- unique와 똑같은 작동을 하는 것을 확인하면,
ioseph=# insert into t values (1);
오류: "t_a_excl" exclusion 제약 조건에 따라 키 값 충돌이 발생했습니다.
상세정보: (a)=(1) 키가 이미 있는 (a)=(1) 키와 충돌합니다.
-- 이게 뭐야, exclude 왜 있는거야? unique로 충분히 이런 기능을 구현할 수 있네!
-- 할 거지만,
ioseph=# drop table t;
DROP TABLE
-- 범위 자료형을 사용하는 테이블을 만들고,
ioseph=# create table t (a int4range);
CREATE TABLE
-- unique를 만들어 보면,
ioseph=# alter table t add unique(a);
ALTER TABLE
ioseph=# insert into t values ('[1, 10)');
INSERT 0 1
ioseph=# insert into t values ('[1, 10)');
오류: 중복된 키 값이 "t_a_key" 고유 제약 조건을 위반함
상세정보: (a)=([1,10)) 키가 이미 있습니다.
-- 1에서 9사이의 범위랑 겹치는 자료를 저장하지 않으려고 했으나,
ioseph=# insert into t values ('[3,6)');
INSERT 0 1
-- 잘 저장되어,
ioseph=# truncate t;
TRUNCATE TABLE
ioseph=# alter table t drop constraint t_a_key;
ALTER TABLE
-- 이번에는 겹치는지를 확인하는 && 연산자를 사용해서 exclude 제약조건을 만드려고 했으나,
ioseph=# alter table t add exclude (a with &&);
오류: &&(anyrange,anyrange) 연산자는 "range_ops" 연산자 패밀리 구성원이 아닙니다.
상세정보: 제외 연산자는 해당 제약 조건용 인덱스 연산자 클래스의 소속이어야 합니다.
-- 이 연산을 할 때 인덱스를 사용하려면, gist나, gin 인덱스로 만들어야 하고,
ioseph=# alter table t add exclude using gist (a with &&);
ALTER TABLE
ioseph=# insert into t values ('[1, 10)');
INSERT 0 1
-- 의도한 대로 겹치는 자료가 입력되면,
ioseph=# insert into t values ('[3,6)');
오류: "t_a_excl" exclusion 제약 조건에 따라 키 값 충돌이 발생했습니다.
상세정보: (a)=([3,6)) 키가 이미 있는 (a)=([1,10)) 키와 충돌합니다.
이런식입니다.
멋지죠?
심심하신 분은 이 문제를 응용프로램 코드로, 엄청난 자료를 대상으로 구현하겠다 생각하고 코드를 짜보면 알게 될 것입니다.
아하, exclude!
primary key : 기본키
foreign key : 참조키
unique key : 고유키
exclude key(?): 제외키 이렇게 번역할까.. 고민을 하다가
잠깐 설명문을 써 봤습니다.
|