Unique Constraint (uq) คือ กฎที่ใช้ในฐานข้อมูล (Database) เพื่อบังคับให้ข้อมูลในคอลัมน์ (Column) หรือกลุ่มของคอลัมน์ที่กำหนด ห้ามมีค่าซ้ำกัน (Duplicated Value) โดยเด็ดขาด ช่วยรักษาความถูกต้องของข้อมูล (Data Integrity) แตกต่างจาก Primary Key คือสามารถอนุญาตให้มีค่า NULL ได้ (ขึ้นอยู่กับระบบฐานข้อมูล) และกำหนดได้หลายอันต่อหนึ่งตาราง การเพิ่ม โดยการ alter จะต้องมีการเตรียมการก่อน
คุณสมบัติหลักของ Unique Constraint
- ป้องกันข้อมูลซ้ำ: บังคับให้ค่าในคอลัมน์ที่ระบุต้องแตกต่างกันในแต่ละแถว (Row)
- รองรับ NULL Value: โดยทั่วไปยอมรับค่า
NULLได้มากกว่า 1 ค่า (NULL ถือว่าไม่ซ้ำกันในหลายระบบ) - ใช้ได้หลายคอลัมน์: สามารถกำหนด
UNIQUEบนคอลัมน์เดียว หรือรวมหลายคอลัมน์ (Composite Unique Key) - สร้างดัชนีอัตโนมัติ: เมื่อสร้าง Unique Constraint ระบบมักจะสร้าง Unique Index ให้โดยอัตโนมัติเพื่อประสิทธิภาพในการค้นหา
ข้อแตกต่างระหว่าง UNIQUE และ PRIMARY KEY
| คุณสมบัติ | Primary Key | Unique Key |
|---|---|---|
| ความซ้ำ | ห้ามซ้ำ | ห้ามซ้ำ |
| ค่าว่าง (NULL) | ห้ามเป็น NULL | เป็น NULL ได้ (มักจะได้ 1 ค่า) |
| จำนวนต่อตาราง | มีได้เพียง 1 เดียว | มีได้หลายข้อ |
| Index เริ่มต้น | Clustered Index | Non-clustered Index |
Query ค้นหา value ที่ซ้ำ
สิ่งที่ต้องเช็คก่อนทำ Unique Constraint (uq) คือ ต้องไม่มี data เดิมทำได้โดยการ หา value
SELECT
PP_USERNAME,
COUNT(*) as DuplicateCount
FROM PP_USERS
WHERE PP_USERNAME IS NOT NULL
GROUP BY PP_USERNAME
HAVING COUNT(*) > 1;
- เป้าหมายคือ column PP_USERNAME
- ในตาราง PP_USERS
Query ลบ value ที่ซ้ำ
ถ้ามี value ที่ซ้ำเราต้อง DELETE ออกก่อนที่จะทำ Unique Constraint (uq)
WITH CTE AS (
SELECT
PP_ID,
PP_USERNAME,
ROW_NUMBER() OVER (
PARTITION BY PP_USERNAME
ORDER BY PP_ID DESC
) AS RowNum
FROM PP_USERS
WHERE PP_USERNAME IS NOT NULL
)
DELETE FROM CTE
WHERE RowNum > 1;
- เป้าหมายคือ column PP_USERNAME
- ในตาราง PP_USERS
- PRIMARY KEY คือ PP_ID
สร้างพร้อมตาราง
CREATE TABLE PP_USERS (
PP_ID int NOT NULL,
PP_EMAIL varchar(255) UNIQUE, -- กำหนดให้ Email ไม่ซ้ำกัน
PP_USERNAME varchar(255),
CONSTRAINT UC_User UNIQUE (PP_ID, PP_USERNAME)
);
Alter ตารางเดิม
ALTER TABLE PP_USERS ADD CONSTRAINT UC_PP_USERNAME UNIQUE (PP_USERNAME);
อ่านเพิ่มเติม