Auto-increment (SERIAL/BIGSERIAL): 4/8 bytes, sequential → tốt cho B-tree index locality, dễ debug, nhưng lộ business info (competitors đoán số records), không an toàn cho distributed systems (cần central counter).
- UUID v4: 128-bit random, globally unique không cần coordination — perfect cho microservices/distributed; nhưng random → B-tree index fragmentation (random inserts vào random positions → page splits, bloat), 16 bytes (4x lớn hơn int), khó đọc/debug.
- UUID v7 (RFC 9562, 2024): time-ordered UUID — 48-bit Unix timestamp milliseconds prefix + random suffix → sequential như auto-increment nhưng globally unique.
- Lợi ích v7: B-tree friendly (sequential inserts → không fragmentation), globally unique, có thể sort by creation time, không lộ total count.
- PostgreSQL 17+ có
gen_random_uuid()v4 built-in; v7 cần extensionpg_uuidv7hoặc generate ở app layer (uuidv7npm package). - CUID2/NanoID: alternatives — shorter, URL-safe, random nhưng không có timestamp prefix.
- Khi nào dùng UUID: public-facing IDs (URLs, APIs — tránh enumeration attacks), distributed systems, IDs cần generate ở client/app trước khi DB insert.
- Khi dùng BIGINT: internal tables không expose ra ngoài, performance-critical tables với many JOINs.