엄밀히 말하면, 고유 한 nullable 열 (또는 열 집합)은 한 번만 NULL (또는 NULL 레코드)이 될 수 있습니다. 동일한 값 (NULL 포함)이 두 번 이상 있으면 고유 제약 조건을 위반하는 것이 분명하기 때문입니다.
그러나 이것이 "고유 한 nullable 열"개념이 유효 함을 의미하지는 않습니다. 관계형 데이터베이스에서 실제로 구현하려면 이러한 종류의 데이터베이스가 제대로 작동하도록 정규화되어야하며, 정규화에는 일반적으로 엔터티 간의 관계를 설정하기 위해 여러 (엔티티가 아닌) 추가 테이블을 추가해야한다는 점을 명심해야합니다. .
하나의 "고유 한 nullable 열"만 고려하여 기본 예제를 살펴 보겠습니다. 더 많은 열로 쉽게 확장 할 수 있습니다.
다음과 같은 테이블로 표시된 정보를 가정합니다.
create table the_entity_incorrect
(
id integer,
uniqnull integer null, /* we want this to be "unique and nullable" */
primary key (id)
);
uniqnull을 분리하고 두 번째 테이블을 추가하여 uniqnull 값과 the_entity 사이의 관계를 설정하여이를 수행 할 수 있습니다 (uniqnull이 the_entity "내부"에있는 대신).
create table the_entity
(
id integer,
primary key(id)
);
create table the_relation
(
the_entity_id integer not null,
uniqnull integer not null,
unique(the_entity_id),
unique(uniqnull),
/* primary key can be both or either of the_entity_id or uniqnull */
primary key (the_entity_id, uniqnull),
foreign key (the_entity_id) references the_entity(id)
);
uniqnull 값을 the_entity의 행에 연결하려면 the_relation에 행을 추가해야합니다.
the_entity의 행에 대해 uniqnull 값이 연결되지 않은 경우 (즉, the_entity_incorrect에 NULL을 넣은 값) the_relation에 행을 추가하지 않습니다.
uniqnull의 값은 모든 the_relation에 대해 고유하며, the_entity의 각 값에 대해 기본 및 외래 키가이를 적용하기 때문에 the_relation에 최대 하나의 값이있을 수 있습니다.
그런 다음 uniqnull의 값 5가 the_entity id 3과 연결되는 경우 다음을 수행해야합니다.
start transaction;
insert into the_entity (id) values (3);
insert into the_relation (the_entity_id, uniqnull) values (3, 5);
commit;
그리고 the_entity에 대한 id 값 10에 uniqnull 대응 항목이 없으면 다음 작업 만 수행합니다.
start transaction;
insert into the_entity (id) values (10);
commit;
이 정보를 비정규 화하고 the_entity_incorrect와 같은 테이블이 보유 할 데이터를 얻으려면 다음을 수행해야합니다.
select
id, uniqnull
from
the_entity left outer join the_relation
on
the_entity.id = the_relation.the_entity_id
;
"왼쪽 외부 조인"연산자는 the_entity의 모든 행이 결과에 나타나도록하여 the_relation에 일치하는 열이없는 경우 uniqnull 열에 NULL을 넣습니다.
잘 정규화 된 데이터베이스 (및 이에 상응하는 비정규 화 뷰 및 절차)를 설계하는 데 며칠 (또는 몇 주 또는 몇 달) 동안 소요 된 모든 노력은 수년 (또는 수십 년)의 고통과 낭비되는 리소스를 절약 할 수 있다는 점을 기억하십시오.