Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> SQL

Unique Key (Khóa duy nhất) trong RDBMS: Khác biệt với Primary Key


Nhiều người nhầm lẫn Unique Key và Primary Key vì cả hai đều đảm bảo tính duy nhất (uniqueness). Tuy nhiên, chúng khác biệt căn bản về ngữ nghĩa, ràng buộc NULL và số lượng.

Bảng so sánh chi tiết

Tiêu chíPrimary Key (PK)Unique Key (UK)
Mục đíchĐịnh danh chính thức (Entity Identity) cho tuple.Ngăn chặn trùng lặp giá trị trên cột/cột tổ hợp (Business Rule).
Giá trị NULLKHÔNG được phép (NOT NULL bắt buộc).Được phép (thường cho phép 1 NULL, tùy DBMS).
Số lượng/bảngChỉ 1 PK.**Nhiều** UK (0, 1, hoặc nhiều).
Sửa đổi giá trịKhông nên thay đổi (immutable). FK tham chiếu đến nó.Có thể thay đổi (nếu không bị FK tham chiếu).
IndexTự động tạo Unique Index (Clustered trong SQL Server/MySQL InnoDB).Tự động tạo Unique Index (Non-clustered thường).
Foreign Key tham chiếuCó (chuẩn).Có (tham chiếu UK thay vì PK - hợp lệ SQL standard).
Clustered Index mặc địnhCó (SQL Server, MySQL InnoDB).Không (mặc định Non-clustered).

Ví dụ minh họa

CREATE TABLE Employee (
  Emp_ID INT PRIMARY KEY,              -- PK: NOT NULL, Unique, 1/bảng
  Email VARCHAR(100) UNIQUE,           -- UK: Cho phép NULL, Unique
  Phone VARCHAR(20) UNIQUE,            -- UK: Cho phép NULL, Unique
  SSN CHAR(12) UNIQUE NOT NULL,        -- UK: NOT NULL + Unique = Candidate Key
  Username VARCHAR(50) UNIQUE NOT NULL -- UK: NOT NULL + Unique = Candidate Key
);

Phân tích:

  • Emp_ID: PK - định danh nhân viên.
  • Email, Phone: UK - nghiệp vụ yêu cầu không trùng, nhưng có thể chưa có (NULL).
  • SSN, Username: UK + NOT NULL = **Candidate Key** (ứng viên PK).

NULL trong Unique Key - Chi tiết theo DBMS

DBMSSố NULL cho phép trên Unique ColumnGhi chú
PostgreSQLNhiều NULLNULL != NULL (theo SQL Standard).
SQL Server1 NULL (mặc định), nhiều nếu WHERE col IS NOT NULL (Filtered Index).Cân nhắc Filtered Unique Index.
MySQL (InnoDB)Nhiều NULLNULL != NULL.
OracleNhiều NULLNULL != NULL.
SQLiteNhiều NULLNULL != NULL.

Theo SQL Standard (ISO/IEC 9075): UNIQUE constraint cho phép nhiều NULL vì NULL không bằng nhau.

Khi nào dùng Unique Key?

  • Cột nghiệp vụ **bắt buộc duy nhất** nhưng **không phù hợp làm PK**: Email, Phone, Username, CMND/CCCD, Mã số thuế, Serial Number, ISBN, SKU...
  • Composite Unique Key: UNIQUE (OrderID, ProductID) trên bảng OrderDetail (ngăn trùng dòng).
  • Partial Unique Index (Filtered Index): CREATE UNIQUE INDEX idx_active_email ON Users(Email) WHERE IsActive = 1 (SQL Server, PostgreSQL) - chỉ unique cho user active.

Best Practices

  1. Luôn có **một PK** (Surrogate Key: ID/BIGINT/UUID) cho mọi bảng.
  2. Đặt **Unique Constraint/Index** cho mọi Natural Key / Business Key (Email, Phone, Code...).
  3. Naming convention: UK_table_column hoặc UQ_table_column.
  4. Nếu UK là NOT NULL -> nó là **Candidate Key**. Doc rõ ràng: "Alternate Key".
  5. Tránh dùng UK làm target của FK (dùng PK) trừ khi có lý do mạnh (legacy, sharding).

Tóm tắt nhớ lâu

Primary Key = "Căn cước công dân" của hàng dữ liệu: Riêng, duy nhất, không bao giờ đổi, không bao giờ rỗng, chỉ có 1.
Unique Key = "Số điện thoại/Email" cá nhân: Duy nhất, nhưng có thể chưa có (NULL), có thể đổi, một người có thể có nhiều (nhiều UK/bảng).