UUID là gì? So sánh v1, v4, v7 và khi nào nên dùng
19/07/2026
Nếu bạn từng làm việc với cơ sở dữ liệu, API hay hệ thống phân tán, chắc chắn bạn đã gặp những chuỗi kỳ lạ kiểu 550e8400-e29b-41d4-a716-446655440000. Đó chính là UUID — một trong những cách phổ biến nhất để tạo định danh duy nhất mà không cần hỏi ý kiến bất kỳ máy chủ trung tâm nào. Bài viết này giải thích UUID là gì, so sánh các phiên bản v1, v4, v7 và quan trọng nhất: khi nào bạn thực sự nên dùng từng loại, đặc biệt dưới góc nhìn của backend developer làm việc với PostgreSQL.
UUID là gì?
UUID (Universally Unique Identifier), trên nền tảng Microsoft còn gọi là GUID (Globally Unique Identifier), là một định danh 128-bit. Mục tiêu thiết kế của nó là: hai bên bất kỳ, ở bất kỳ đâu, tại bất kỳ thời điểm nào, đều có thể tự sinh ra một UUID và gần như chắc chắn không bao giờ trùng nhau — mà không cần điều phối tập trung.
128 bit đó thường được biểu diễn dưới dạng 32 ký tự hex, chia thành 5 nhóm theo định dạng 8-4-4-4-12, ngăn cách bởi dấu gạch nối:
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
8 4 4 4 12
Trong đó có hai vị trí mang ý nghĩa đặc biệt: ký tự M cho biết version (phiên bản, ví dụ 1, 4, 7), còn ký tự N mã hoá variant (biến thể của chuẩn). Nhờ vậy, chỉ cần nhìn vào một UUID là bạn đã đọc được nó thuộc phiên bản nào.
Các phiên bản UUID phổ biến
UUID v1 — dựa trên thời gian + MAC address
v1 kết hợp timestamp (thời gian tính theo đơn vị 100 nanosecond kể từ năm 1582), một chuỗi clock sequence và địa chỉ MAC của máy sinh ra nó.
- Ưu điểm: gần như không thể trùng vì gắn với phần cứng cụ thể và thời gian; ẩn chứa thông tin thời điểm tạo.
- Nhược điểm: lộ MAC address và thời gian tạo — một vấn đề riêng tư và bảo mật (chính lỗ hổng này từng giúp truy vết tác giả virus Melissa). Cách sắp xếp byte của timestamp cũng khiến v1 không sort tự nhiên theo thời gian.
UUID v4 — ngẫu nhiên hoàn toàn
v4 là phiên bản phổ biến nhất. Ngoài các bit cố định cho version và variant, toàn bộ 122 bit còn lại được sinh ngẫu nhiên.
- Ưu điểm: đơn giản, không phụ thuộc phần cứng, không lộ thông tin gì về máy hay thời gian; sinh được ở bất cứ đâu chỉ cần nguồn ngẫu nhiên tốt.
- Nhược điểm: hoàn toàn không có thứ tự — đây là gót chân Achilles khi dùng làm khoá chính trong DB (xem phần dưới).
UUID v7 — timestamp + random, sắp xếp được theo thời gian
v7 là chuẩn mới (RFC 9562, năm 2024) sinh ra để giải quyết đúng điểm yếu của v4. Nó ghép 48 bit timestamp Unix mili-giây ở đầu, phần còn lại là bit ngẫu nhiên.
- Ưu điểm: vừa duy nhất như v4, vừa sortable theo thời gian tạo (UUID sinh sau luôn lớn hơn về mặt từ điển). Thân thiện với index của database, không lộ MAC như v1.
- Nhược điểm: tiết lộ thời điểm tạo (thường chấp nhận được); còn khá mới nên một số thư viện/ngôn ngữ cũ chưa hỗ trợ sẵn.
Bạn có thể thử sinh và quan sát trực tiếp từng phiên bản bằng công cụ UUID Generator của chúng tôi.
Vì sao v4 phổ biến và có sợ bị trùng không?
v4 thắng thế vì nó đơn giản và an toàn về mặt riêng tư: không cần đọc phần cứng, không cần đồng hồ đồng bộ, chỉ cần một bộ sinh số ngẫu nhiên. Hầu hết ngôn ngữ hiện đại đều có sẵn hàm tạo v4.
Còn xác suất trùng? Với 122 bit ngẫu nhiên, không gian giá trị là khoảng 5.3 × 1036. Theo bài toán sinh nhật, bạn phải sinh cỡ một tỷ UUID mỗi giây trong khoảng 85 năm mới có xác suất trùng đáng kể là 50%. Trên thực tế, khả năng trùng là không đáng lo — điều đáng lo hơn là chất lượng nguồn ngẫu nhiên (phải dùng CSPRNG, không dùng Math.random()).
Góc nhìn backend/DB: dùng UUID làm khoá chính có đáng không?
Đây là quyết định thiết kế quan trọng, và nó là một đánh đổi so với khoá tự tăng (auto-increment / BIGSERIAL).
Ưu điểm của UUID làm primary key:
- Không lộ số lượng bản ghi: ID
/users/1042cho biết bạn có ~1000 user; UUID thì không tiết lộ gì. - Tạo được ở phía client/ứng dụng: không cần round-trip xuống DB để lấy ID, giúp code insert và liên kết quan hệ dễ hơn.
- Dễ merge và sharding: gộp dữ liệu từ nhiều nguồn hay nhiều shard mà không sợ đụng ID — cực kỳ hữu ích trong hệ phân tán.
Nhược điểm cần cân nhắc:
- Tốn dung lượng: UUID là 16 byte, so với 4 byte (
INT) hay 8 byte (BIGINT). Khoá to hơn nghĩa là mọi index phụ tham chiếu tới nó cũng phình theo. - Index kém locality với v4: vì v4 ngẫu nhiên, mỗi bản ghi mới được chèn vào một vị trí "lung tung" trong B-tree, gây phân mảnh trang (page split) và giảm hiệu năng ghi. Đây chính là lý do v7 (và ULID) ra đời: phần timestamp ở đầu khiến ID mới luôn được ghi nối tiếp cuối index, khôi phục lại tính tuần tự.
Với PostgreSQL, hãy dùng kiểu dữ liệu uuid nguyên bản (lưu nhị phân 16 byte) thay vì varchar(36) — vừa tiết kiệm chỗ vừa nhanh hơn. Lời khuyên thực dụng: nếu cần khoá chính dạng UUID, hãy ưu tiên v7 để giữ hiệu năng index; nếu bảng nhỏ hoặc nội bộ, BIGSERIAL vẫn là lựa chọn đơn giản và hiệu quả nhất.
Bảng so sánh nhanh v1 / v4 / v7
| Tiêu chí | v1 | v4 | v7 |
|---|---|---|---|
| Cách sinh | Timestamp + MAC | Ngẫu nhiên toàn phần | Timestamp (ms) + random |
| Sắp xếp theo thời gian | Không (byte đảo) | Không | Có |
| Lộ thông tin | MAC + thời gian | Không | Thời gian tạo |
| Thân thiện index DB | Trung bình | Kém | Tốt |
| Độ phổ biến / hỗ trợ | Cũ, ít dùng | Rất phổ biến | Mới, đang tăng |
| Dùng khi | Hệ thống legacy | ID chung, token, mặc định | Khoá chính DB, log có thứ tự |
Ví dụ và cách sinh trong code
Một vài UUID mẫu (để ý ký tự thứ 13 chỉ version):
v1: 2f7c8e00-5a3b-11ef-9c2d-0242ac120002
v4: 550e8400-e29b-41d4-a716-446655440000
v7: 018f9a2b-7c3d-7e10-8b45-9f1c2a3d4e5f
Trong JavaScript/Node (v4, có sẵn trong trình duyệt hiện đại và Node 19+):
// Sinh UUID v4 bằng Web Crypto API
const id = crypto.randomUUID();
console.log(id); // "550e8400-e29b-41d4-a716-446655440000"
Trong PostgreSQL (v4 có sẵn từ bản 13):
CREATE TABLE users (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name text NOT NULL
);
-- Sinh trực tiếp
SELECT gen_random_uuid();
Trong Java (Spring Boot) — v4 có sẵn, v7 cần thư viện hỗ trợ:
UUID id = UUID.randomUUID(); // v4
System.out.println(id);
Kết luận
UUID là công cụ mạnh để tạo định danh duy nhất mà không cần điều phối trung tâm. Tóm tắt lựa chọn:
- Cần một ID ngẫu nhiên, an toàn, dùng chung mọi nơi → v4.
- Cần khoá chính trong database hoặc ID có thứ tự thời gian → v7 (hoặc ULID).
- Chỉ nên gặp v1 trong hệ thống cũ; tránh dùng cho dự án mới vì lộ MAC.
Muốn sinh nhanh UUID ở nhiều phiên bản, sao chép chỉ với một cú click và kiểm tra định dạng ngay trên trình duyệt (không gửi dữ liệu lên server)? Hãy dùng thử UUID Generator của DevToolHub.