พูดอย่างเคร่งครัดคอลัมน์ที่เป็นโมฆะที่ไม่ซ้ำกัน (หรือชุดของคอลัมน์) สามารถเป็น NULL (หรือบันทึกของ NULL) ได้เพียงครั้งเดียวเนื่องจากมีค่าเดียวกัน (และรวมถึง NULL) มากกว่าหนึ่งครั้งอย่างเห็นได้ชัดว่าละเมิดข้อ จำกัด เฉพาะ
อย่างไรก็ตามนั่นไม่ได้หมายความว่าแนวคิดของ "คอลัมน์ที่ไม่ซ้ำกัน" นั้นถูกต้อง ในการนำไปใช้จริงในฐานข้อมูลเชิงสัมพันธ์ใด ๆ เราต้องจำไว้ว่าฐานข้อมูลประเภทนี้มีไว้เพื่อให้ทำงานได้อย่างถูกต้องและการทำให้เป็นมาตรฐานมักเกี่ยวข้องกับการเพิ่มตารางพิเศษ (ที่ไม่ใช่เอนทิตี) หลายตารางเพื่อสร้างความสัมพันธ์ระหว่างเอนทิตี .
มาดูตัวอย่างพื้นฐานโดยพิจารณาจาก "คอลัมน์ที่เป็นค่าว่างที่ไม่ซ้ำกัน" เพียงคอลัมน์เดียวจึงง่ายที่จะขยายไปยังคอลัมน์ดังกล่าวเพิ่มเติม
สมมติว่าเราแสดงข้อมูลด้วยตารางดังนี้:
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 "inside" 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 กับแถวใน _entity เราต้องเพิ่มแถวใน the_relation
สำหรับแถวใน _entity นั้นไม่มีการเชื่อมโยงค่า uniqnull (เช่นสำหรับแถวที่เราจะใส่ NULL ใน the_entity_incorrect) เราก็ไม่เพิ่มแถวใน the_relation
โปรดทราบว่าค่าสำหรับ uniqnull จะไม่ซ้ำกันสำหรับ the_relation ทั้งหมดและโปรดสังเกตด้วยว่าสำหรับแต่ละค่าใน _entity อาจมีได้ไม่เกินหนึ่งค่าใน the_relation เนื่องจากคีย์หลักและคีย์ภายนอกบังคับใช้สิ่งนี้
จากนั้นหากต้องเชื่อมโยงค่า 5 สำหรับ uniqnull กับ 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;
และถ้าค่า id เป็น 10 สำหรับ the_entity ไม่มีคู่ 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
;
ตัวดำเนินการ "left outer join" ทำให้แน่ใจว่าแถวทั้งหมดจาก the_entity จะปรากฏในผลลัพธ์โดยใส่ NULL ในคอลัมน์ uniqnull เมื่อไม่มีคอลัมน์ที่ตรงกันอยู่ใน the_relation
โปรดจำไว้ว่าความพยายามใด ๆ ที่ใช้เวลาหลายวัน (หรือหลายสัปดาห์หรือหลายเดือน) ในการออกแบบฐานข้อมูลที่เป็นมาตรฐาน (และมุมมองและขั้นตอนการทำให้เป็นมาตรฐานที่สอดคล้องกัน) จะช่วยให้คุณประหยัดความเจ็บปวดและสิ้นเปลืองทรัพยากรได้เป็นเวลาหลายปี (หรือหลายทศวรรษ)