Hai cách chọn khóa chính, khác nhau ở chỗ khóa có "ý nghĩa nghiệp vụ" hay không:
- Natural key: dữ liệu thật (email, SSN, ISBN). Ưu: lấy giá trị khỏi join. Nhược: có thể đổi (user đổi email → phải sửa hết FK trỏ tới), thực tế có thể trùng (SSN nhập sai), và lộ dữ liệu nghiệp vụ trong URL.
- Surrogate key: ID nhân tạo vô nghĩa —
SERIAL/BIGSERIALhoặc UUID. Ưu: không bao giờ đổi → FK ổn định, không lộ thông tin, đơn giản.
Thực hành chuẩn: dùng surrogate làm PK, và đặt UNIQUE trên natural key nếu cần ép tính duy nhất:
sql
id BIGSERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULLNếu chọn UUID, UUID v7 là lựa chọn tốt: vừa duy nhất toàn cục vừa thân thiện với B-tree (sinh tăng dần theo thời gian nên ít phân mảnh index).
Two ways to pick a primary key, differing in whether the key carries "business meaning":
- Natural key: real data (email, SSN, ISBN). Pro: read the value without a join. Cons: it can change (user changes email → you must update every FK pointing to it), may duplicate in practice (a mistyped SSN), and leaks business data into URLs.
- Surrogate key: an artificial meaningless ID —
SERIAL/BIGSERIALor UUID. Pros: never changes → stable FKs, no info leak, simple.
Standard practice: use a surrogate as the PK, and add UNIQUE on the natural key when you need to enforce uniqueness:
sql
id BIGSERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULLIf you choose UUID, UUID v7 is a good pick: globally unique and B-tree friendly (it increases over time, so it fragments the index far less).