Khi thiết kế database, PRIMARY KEY và UNIQUE đều có thể được dùng để đảm bảo dữ liệu không bị trùng.
Vì vậy, một câu hỏi khá phổ biến trong phỏng vấn là:
Nếu cả hai đều không cho phép trùng dữ liệu, vậy PRIMARY KEY và UNIQUE khác nhau ở đâu?
Câu trả lời ngắn gọn:
PRIMARY KEY dùng để định danh duy nhất mỗi dòng trong bảng, còn UNIQUE dùng để đảm bảo một hoặc một nhóm giá trị không bị trùng.
1. PRIMARY KEY và UNIQUE dùng để làm gì?
Giả sử có bảng users:
| id | username | |
|---|---|---|
| 1 | an123 | [email protected] |
| 2 | binh456 | [email protected] |
| 3 | cuong789 | [email protected] |
Ta có thể thiết kế:
CREATE TABLE users (
id NUMBER PRIMARY KEY,
username VARCHAR2(50) UNIQUE,
email VARCHAR2(100) UNIQUE
);
Ở đây:
PRIMARY KEY
→ id phải duy nhất
→ dùng để xác định một user
UNIQUE
→ username không được trùng
→ email không được trùng
Ví dụ:
INSERT INTO users
VALUES (1, 'an123', '[email protected]');
Nếu tiếp tục:
INSERT INTO users
VALUES (2, 'an123', '[email protected]');
database sẽ từ chối vì username = 'an123' đã tồn tại.
Tương tự, hai user không thể có cùng email nếu email được đặt UNIQUE.
2. Điểm khác biệt quan trọng nhất
Có thể phân biệt bằng bảng sau:
| PRIMARY KEY | UNIQUE | |
|---|---|---|
| Mục đích | Định danh row | Đảm bảo không trùng |
| Một bảng có bao nhiêu? | Chỉ 1 | Có thể có nhiều |
| Cho phép NULL? | Không | Oracle cho phép |
| Có thể gồm nhiều cột? | Có | Có |
| Dùng làm định danh chính? | Có | Không bắt buộc |
Ví dụ một bảng chỉ có thể có:
PRIMARY KEY (id)
nhưng có thể có nhiều UNIQUE:
UNIQUE (username),
UNIQUE (email)
Có thể nhớ đơn giản:
PRIMARY KEY trả lời câu hỏi: “Dòng này là ai?”
UNIQUE trả lời câu hỏi: “Giá trị này có bị trùng không?”
3. PRIMARY KEY và UNIQUE có cho phép NULL không?
Đây là một điểm rất hay được hỏi khi phỏng vấn.
PRIMARY KEY
Không được chứa NULL.
id NUMBER PRIMARY KEY
id bắt buộc phải có giá trị và phải duy nhất.
UNIQUE
Trong Oracle, constraint UNIQUE cho phép NULL. Đặc biệt, một unique constraint có thể cho phép nhiều row có giá trị NULL vì Oracle không coi các NULL là bằng nhau trong ngữ cảnh này. (docs.oracle.com)
Ví dụ:
CREATE TABLE users (
id NUMBER PRIMARY KEY,
email VARCHAR2(100) UNIQUE
);
Các dòng như sau có thể tồn tại:
| id | |
|---|---|
| 1 | [email protected] |
| 2 | NULL |
| 3 | NULL |
Nhưng:
[email protected]
[email protected]
sẽ vi phạm UNIQUE.
Lưu ý: hành vi liên quan đến
NULLcó thể khác giữa các hệ quản trị database, vì vậy bạn nên nói rõ đang xét Oracle, MySQL, PostgreSQL….
4. Có thể dùng nhiều cột với PRIMARY KEY và UNIQUE không?
Có.
Đây được gọi là Composite Key / Composite Unique Constraint.
Ví dụ bảng order_items:
| order_id | product_id | quantity |
|---|---|---|
| 1 | 10 | 2 |
| 1 | 20 | 1 |
| 2 | 10 | 3 |
Ta có thể yêu cầu một sản phẩm chỉ xuất hiện một lần trong cùng một đơn hàng:
CREATE TABLE order_items (
order_id NUMBER,
product_id NUMBER,
quantity NUMBER,
CONSTRAINT pk_order_items
PRIMARY KEY (order_id, product_id)
);
Ở đây:
(order_id, product_id)
kết hợp với nhau để xác định duy nhất một dòng.
Ví dụ:
(1, 10) → hợp lệ
(1, 20) → hợp lệ
(2, 10) → hợp lệ
(1, 10) → trùng
Tương tự, UNIQUE cũng có thể áp dụng cho nhiều cột:
UNIQUE (order_id, product_id)
Điều quan trọng là tính duy nhất được xét trên tổ hợp các cột, không phải từng cột riêng lẻ.
Kết luận
Cả PRIMARY KEY và UNIQUE đều giúp kiểm soát dữ liệu trùng lặp, nhưng mục đích của chúng khác nhau:
PRIMARY KEY
→ Định danh duy nhất một row
→ Mỗi table chỉ có 1
→ Không được NULL
UNIQUE
→ Đảm bảo giá trị không trùng
→ Một table có thể có nhiều
→ Trong Oracle có thể chứa NULL
Nếu cần nhớ nhanh:
PRIMARY KEY = “Dòng này là ai?”
UNIQUE = “Giá trị này có bị trùng không?”


