厳密に言えば、同じ値(これにはNULLを含む)が2回以上あると一意の制約に明らかに違反するため、一意のnull許容列(または列のセット)はNULL(またはNULLのレコード)に1回しかなりません。
ただし、これは「一意のnull許容列」の概念が有効であることを意味するものではありません。これをリレーショナルデータベースに実際に実装するには、この種類のデータベースは正常に機能するように正規化されていることを念頭に置く必要があります。通常、正規化には、エンティティ間の関係を確立するためのいくつかの(非エンティティ)追加のテーブルの追加が含まれます。 。
「一意のnull許容列」を1つだけ考慮して基本的な例を考えてみましょう。このような列に簡単に拡張できます。
次のような表で表される情報があるとします。
create table the_entity_incorrect
(
id integer,
uniqnull integer null, /* we want this to be "unique and nullable" */
primary key (id)
);
これを行うには、uniqnullを離して2番目のテーブルを追加し、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_relationの主キーと外部キーがこれを強制するため、the_relationには最大で1つの値しか存在できないことに注意してください。
次に、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_relationに存在しない場合、the_entityからのすべての行が結果に表示されることを保証し、uniqnull列にNULLを入れます。
十分に正規化されたデータベース(および対応する非正規化のビューと手順)の設計に数日(または数週間または数か月)費やす努力により、数年(または数十年)の苦痛と無駄なリソースを節約できます。