UUID vs Auto-increment - Lựa chọn Primary Key
| Tiêu chí | Auto-increment | UUIDv4 | UUIDv7/ULID |
|---|---|---|---|
| Insert speed | Nhanh nhất | Chậm (random position) | Nhanh (time-sorted) |
| Size | 4-8 bytes | 16 bytes | 16 bytes |
| Predictable | Dễ đoán (enumeration attack) | Không đoán được | Không đoán được |
| Distributed ID gen | Không | Có | Có |
Khuyến nghị của sách
Dùng auto-increment cho internal PK. Nếu cần expose ra external (URL, API), thêm cột UUID riêng:
-- PostgreSQL:
ALTER TABLE users ADD COLUMN uuid UUID NOT NULL DEFAULT gen_random_uuid();
CREATE UNIQUE INDEX users_uuid ON users (uuid);
-- Dùng auto-increment id cho JOIN, uuid cho API/URLCách này được cả hai: JOIN nội bộ nhanh + PK nhỏ (không phình secondary index trong MySQL), còn bên ngoài không đoán được ID.
Nếu phải dùng UUID làm PK
- Chọn UUIDv7 / ULID (time-based, gần như tăng dần) thay vì UUIDv4 (random).
- Lưu dạng BINARY(16) thay vì CHAR(36) để tiết kiệm space - đặc biệt quan trọng với MySQL vì PK được copy vào mọi secondary index.
Liên quan
- Primary Key và thứ tự Insert - vì sao random PK insert chậm
- Heap Table vs Clustered Index - vì sao MySQL nhạy cảm với PK size hơn PostgreSQL