Hai cách sinh khóa chính:
- Auto-increment (
SERIAL/BIGSERIAL): số tăng dần, nhỏ gọn (4/8 byte), index B-tree gọn, dễ debug. Nhược: lộ thông tin (đối thủ đoán được số bản ghi qua id), và không an toàn cho hệ phân tán vì cần bộ đếm trung tâm. - UUID v4: 128-bit ngẫu nhiên, duy nhất toàn cục không cần phối hợp — hợp microservices. Nhược: ngẫu nhiên nên chèn vào vị trí rải rác → phân mảnh index B-tree (page split, phình), to gấp ~4 lần int, khó đọc.
- UUID v7 (RFC 9562): có tiền tố timestamp + phần ngẫu nhiên → vừa tăng dần như auto-increment (thân thiện B-tree, không phân mảnh), vừa duy nhất toàn cục, lại sắp được theo thời gian tạo. Là lựa chọn tốt nhất khi cần UUID.
Quy tắc chọn:
- UUID khi: id công khai (URL/API — tránh dò tuần tự), hệ phân tán, hoặc cần sinh id ở client trước khi ghi DB.
- BIGINT auto-increment khi: bảng nội bộ không lộ ra ngoài, bảng nặng JOIN cần hiệu năng cao.
(PostgreSQL 17+ có sẵn gen_random_uuid() cho v4; v7 dùng extension pg_uuidv7 hoặc sinh ở app.)