0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Chọn Primary Key: INT Tự Tăng vs UUID trong Thiết Kế DB

Đăng vào 5 tháng trước

• 4 phút đọc

Lựa Chọn Primary Key: INT Tự Tăng vs UUID

Khi thiết kế một sơ đồ cơ sở dữ liệu, việc lựa chọn loại primary key là một quyết định quan trọng. Hai lựa chọn phổ biến nhất là INT tự tăngUUID. Mỗi loại có những ưu và nhược điểm riêng, phù hợp với các yêu cầu của ứng dụng khác nhau.

Mục Lục

  1. INT Tự Tăng
  2. UUID (Universally Unique Identifier)
  3. Tác Động Đến Indexing
  4. Vấn Đề An Ninh của ID
  5. Mô Hình Hybrid: Lợi Ích Tốt Nhất
  6. Các Lựa Chọn Thay Thế UUID
  7. Kết Luận
  8. Câu Hỏi Thường Gặp (FAQ)

1. INT Tự Tăng

Ưu Điểm

  • Nhẹ & hiệu quả: Kích thước nhỏ (4/8 byte), chỉ số nhỏ gọn.
  • Hiệu suất cao: Các truy vấn join và tra cứu dựa trên primary key thường nhanh hơn.
  • Dễ hiểu: Giá trị tuần tự, dễ đọc và đoán trước.
  • Tối ưu cho hệ thống tập trung: Phù hợp nếu cơ sở dữ liệu chỉ chạy trên một máy chủ.

Nhược Điểm

  • Ít an toàn khi công khai: Dễ đoán (ví dụ ID 101 → 102).
  • Tiềm năng xung đột trong hệ thống phân tán: Một số máy chủ có thể tạo ID giống nhau.
  • Di chuyển dữ liệu: Khó khăn hơn khi kết hợp dữ liệu từ nhiều nguồn.

2. UUID (Universally Unique Identifier)

Ưu Điểm

  • Độc nhất toàn cầu: Không lo lắng về xung đột ngay cả khi dữ liệu được tạo ra trên các máy chủ khác nhau.
  • An toàn hơn khi công khai: Khó đoán hơn so với INT.
  • Dễ dàng di chuyển: Không cần remapping ID khi kết hợp dữ liệu.
  • Khả năng mở rộng tốt hơn: Lý tưởng cho hệ thống phân tán và đa vùng miền.

Nhược Điểm

  • Kích thước lớn hơn: 16 byte, làm cho chỉ số nặng nề hơn.
  • Ít hiệu quả trong truy vấn: Tra cứu và join chậm hơn so với INT.
  • Phân mảnh chỉ số: UUID v4 ngẫu nhiên, các chèn có thể phân tán khắp cây chỉ số.
  • Khó đọc cho con người: Khó quản lý hoặc đọc thủ công.

3. Tác Động Đến Indexing

PostgreSQL (và MySQL) sử dụng B-Tree index theo mặc định:

  • INT → tuần tự, chèn luôn ở cuối, rất hiệu quả.
  • UUID v4 (ngẫu nhiên) → chèn ngẫu nhiên, gây phân mảnh chỉ số.

Giải Pháp Giảm Thiểu cho UUID

  • Sử dụng UUID v1/v7 (dựa trên thời gian/theo thứ tự) để có thứ tự hơn.
  • Các lựa chọn khác: ULID/KSUID.

4. Vấn Đề An Ninh của ID

  • INT → dễ đoán. Tài nguyên công khai (như /users/124) dễ dàng truy cập.
  • UUID → an toàn hơn cho định danh công khai.

Ghi chú: Mặc dù xác thực quyền truy cập có thể ngăn chặn truy cập trái phép, UUID vẫn tốt hơn như một định danh công khai vì khó đoán.

5. Mô Hình Hybrid: Lợi Ích Tốt Nhất

Nhiều hệ thống lớn sử dụng mô hình kết hợp:

sql Copy
CREATE EXTENSION IF NOT EXISTS "pgcrypto";

CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,  -- PK nội bộ cho hiệu suất DB
    public_id UUID UNIQUE NOT NULL DEFAULT gen_random_uuid(), -- exposed cho client
    name TEXT
);

-- Chỉ số hash đặc biệt cho public_id
CREATE INDEX idx_users_public_id_hash
ON users USING hash (public_id);
  • INT → sử dụng cho các thao tác nội bộ (join, quan hệ, FK).
  • UUID → sử dụng cho định danh công khai.
  • Chỉ số Hash → hiệu quả cho truy vấn chính xác (WHERE public_id = ...).

Với mô hình này:

  • Cơ sở dữ liệu vẫn hiệu quả.
  • API công khai an toàn hơn.
  • Chi phí lưu trữ bổ sung vẫn trong giới hạn hợp lý.

6. Các Lựa Chọn Thay Thế UUID

Ngoài UUID, còn có lựa chọn khác cho định danh duy nhất:

  • UUID v7 → có thứ tự hơn, giảm phân mảnh chỉ số.
  • ULID/KSUID → duy nhất toàn cầu, vẫn duy trì thứ tự thời gian.
  • Snowflake ID → số nguyên 64-bit duy nhất toàn cầu (nhiều hệ thống lớn như Twitter sử dụng).

7. Kết Luận

  • Sử dụng INT Tự Tăng cho PK nội bộ nếu hiệu suất DB là ưu tiên.
  • Sử dụng UUID/ULID cho việc công khai để an toàn hơn.
  • Kết hợp cả hai với chiến lược lập chỉ mục (B-Tree cho INT, Hash Index cho UUID) để đạt được sự cân bằng tốt nhất.

💡 Thực hành tốt nhất:
"PK nội bộ = INT, ID Công khai = UUID với chỉ số hash."

Với điều này, hiệu suất cơ sở dữ liệu vẫn tối ưu, và ứng dụng vẫn an toàn khi công khai định danh ra bên ngoài.

Câu Hỏi Thường Gặp (FAQ)

1. INT tự tăng có an toàn không khi sử dụng trên web?

  • Mặc dù INT tự tăng dễ hiểu và hiệu quả, nhưng việc sử dụng nó trên các ứng dụng công khai có thể dẫn đến rò rỉ thông tin nhạy cảm. UUID thường được khuyên dùng trong trường hợp này.

2. UUID có tốn nhiều dung lượng lưu trữ hơn không?

  • Có, UUID thường lớn hơn INT, điều này có thể ảnh hưởng đến dung lượng lưu trữ và hiệu suất truy vấn.

3. Có cách nào để tối ưu hóa hiệu suất khi sử dụng UUID không?

  • Sử dụng UUID v1 hoặc v7 để giảm phân mảnh, hoặc áp dụng các phương pháp lập chỉ mục khác như chỉ số hash cho các trường UUID.
Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào