1 điểm bởi GN⁺ 2026-03-08 | 1 bình luận | Chia sẻ qua WhatsApp
  • Một đề xuất về việc đưa chức năng tạo và phân tích UUID vào thư viện chuẩn của ngôn ngữ Go đang được thảo luận trên GitHub
  • Người đề xuất đưa ra căn cứ rằng hiện nay phần lớn các dự án server·DB viết bằng Go đều phụ thuộc vào các gói bên ngoài như github.com/google/uuid
  • Các ngôn ngữ lớn như C#, Java, Python đã cung cấp hỗ trợ UUID ở cấp thư viện chuẩn
  • Trong quá trình thảo luận, các vấn đề chính gồm UUIDv7, mức độ tuân thủ RFC 9562, phạm vi bao gồm chức năng phân tích và tính nhất quán của API đã được bàn luận
  • Đề xuất này sau đó được hợp nhất để tiếp tục dưới dạng đề xuất hỗ trợ UUIDv4·UUIDv7 trong gói crypto/rand (#76319)

Tổng quan đề xuất

  • Đưa ra phương án bổ sung API tạo và phân tích UUID vào thư viện chuẩn Go
    • Các phiên bản mục tiêu là UUID v3, v4, v5
    • Căn cứ chính là mức độ phụ thuộc vào gói bên ngoài và các trường hợp được hỗ trợ chuẩn trong những ngôn ngữ khác
  • UUID là một tiêu chuẩn quốc tế được định nghĩa trong RFC 4122 (sau này là RFC 9562)
  • Người đề xuất chỉ ra rằng Go là trường hợp ngoại lệ hiếm hoi trong số các ngôn ngữ lớn khi không có hỗ trợ UUID chuẩn

Phản ứng ban đầu và thảo luận

  • Một số người tham gia nhắc đến việc đã từng có các đề xuất tương tự nhưng bị từ chối trước đó (#23789, #28324)
    • Lý do là việc dùng gói bên ngoài đã đủ thuận tiện, và chu kỳ phát hành linh hoạt hơn so với thư viện chuẩn
  • Người đề xuất lập luận rằng “nếu đa số dự án đều phải import gói bên ngoài mỗi lần, thì thà đưa luôn vào chuẩn còn hơn”
  • Việc nhiều ngôn ngữ đưa UUID vào thư viện chuẩn liên quan đến crypto cũng được nêu làm căn cứ ủng hộ

Phản ánh các phiên bản UUID mới và RFC

  • Một số ý kiến chỉ ra rằng UUID v1~v5 đã cũ, còn v7 là phiên bản mới và nhiều hứa hẹn hơn
    • v7 có nhiều tùy chọn triển khai khác nhau, nên cần theo dõi thêm kết quả áp dụng
  • Bản nháp RFC khuyến nghị không nên phân tích UUID một cách không cần thiết mà nên xử lý nó như một định danh opaque
  • Sau khi RFC 9562 được phát hành chính thức, thảo luận liên quan đã chuyển trọng tâm sang hỗ trợ UUIDv7

Chỉnh sửa và hợp nhất đề xuất

  • Đến năm 2025, khi RFC 9562 được chính thức hóa, đã xuất hiện nhắc tới việc PostgreSQL 18 hỗ trợ UUIDv7
  • Sau đó phía Go khởi động một đề xuất riêng về việc chỉ bổ sung chức năng tạo UUIDv4·UUIDv7 trong gói crypto/rand (#76319)
    • Chức năng phân tích bị loại trừ theo khuyến nghị của RFC
  • Đề xuất gốc (#62026) được đánh dấu là trùng lặp (duplicate) và bị đóng

Thảo luận thiết kế API

  • Có thảo luận về việc liệu hành vi mặc định của uuid.New() nên là v4 hay nên để ngỏ khả năng thay đổi trong tương lai
    • Một số ý kiến đề xuất luôn cố định là v4 vì “nếu đổi phiên bản sau này có thể phát sinh vấn đề tương thích”
  • Thảo luận về việc có nên cung cấp các phương thức như Compare, MustParse, Parse hay không
    • Có ý kiến cho rằng Compare là cần thiết để hỗ trợ UUID có thể sắp xếp theo định nghĩa của RFC
    • MustParse được đưa vào để giữ tính nhất quán với các hàm Must* khác trong chuẩn
  • Kết luận là phương thức IsZero() không cần thiết cho kiểu UUID
  • Nhiều đề xuất thiết kế khác nhau cũng được đưa ra như thêm struct Generator, tách kiểu theo từng phiên bản (UUIDv4, UUIDv7, v.v.)
  • Một số ý kiến chỉ ra sự mơ hồ của hàm New() và đề xuất chỉ cung cấp các hàm chỉ rõ phiên bản (NewV4, NewV7)

Các vấn đề kỹ thuật chính

  • Có thảo luận về việc định nghĩa sắp xếp UUID (sorting) có phải chỉ tồn tại rõ ràng ở v6·v7 hay không
  • Xem xét cách triển khai bảo đảm sắp xếp theo thời gian khi tạo UUIDv7ngăn xung đột đồng thời (theo cơ chế counter)
  • Có ý kiến chỉ ra giới hạn của thiết kế một kiểu duy nhất do khác biệt ý nghĩa giữa các phiên bản (ví dụ: v1 chứa địa chỉ MAC, v7 dựa trên thời gian)
  • Một số người đề xuất tách kiểu theo phiên bản và bổ sung các phương thức chuyển đổi tường minh như AsV4(), AsV7()

Kết luận và trạng thái hiện tại

  • Cộng đồng Go nhìn chung đồng ý rằng cần có hỗ trợ UUID chuẩn
  • Tuy vậy, để giữ sự đơn giản của thư viện chuẩntuân thủ khuyến nghị của RFC
    • chức năng phân tích bị loại bỏ
    • chỉ bổ sung chức năng tạo UUIDv4·UUIDv7 vào crypto/rand
  • Đề xuất gốc (#62026) đã được hợp nhất vào đề xuất #76319 và hiện đang tiếp tục,
    đưa hỗ trợ UUID chuẩn trong ngôn ngữ Go đến gần giai đoạn được chính thức hóa hơn

1 bình luận

 
GN⁺ 2026-03-08
Ý kiến trên Hacker News
  • Thật thú vị khi có người nói UUID phiên bản 1~5 đã lỗi thời
    Nhưng v4 vẫn có tính ngẫu nhiên cao nhất và được khuyến nghị làm khóa chính để tránh vấn đề hotspot và các vấn đề về quyền riêng tư trong DB phân tán
    Liên kết tham khảo: Tài liệu UUID của CockroachDB, Hướng dẫn UUID của Google Cloud Spanner

    • Tôi cũng thấy cách nói đó kỳ lạ. v7 tốt khi cần tính đơn điệu, nhưng dấu thời gian có thể làm lộ thông tin hệ thống. Vì vậy v4 vẫn hoàn toàn hợp lệ
    • Tôi cho rằng cách dùng từ “outdated” là không phù hợp. Vấn đề là không khớp yêu cầu, chứ không phải vì nó cũ
      Mỗi phiên bản UUID (bao gồm cả v4) đều có khuyết điểm trong những tình huống nhất định. Trên thực tế, nhiều tổ chức tự định nghĩa giá trị 128-bit thuần túy để dùng thay cho UUID tiêu chuẩn
      Cuối cùng thì ngày càng có nhiều yêu cầu phức tạp vượt quá giới hạn thiết kế của UUID
    • v4 là lựa chọn mặc định, chỉ dùng phiên bản khác khi thật sự cần giữ thứ tự
    • Nếu thực sự cần 128 bit ngẫu nhiên thì cứ dùng số ngẫu nhiên 128 bit là được. Không cần phải ép vào định dạng UUID
    • Nhưng v4 có thể làm chèn B-Tree trở nên lộn xộn. Tôi từng học rằng v7 nhanh hơn nhiều nhờ hiệu quả cache trang của kernel
  • Thật vui khi hôm nay HN có một mẩu tin nhỏ liên quan đến Go như thế này
    Dạo này toàn là tương lai của lập trình hay chuyện AI, nên chủ đề kỹ thuật kiểu này thấy mới mẻ

    • Lâu rồi mới thấy lại một cuộc thảo luận kỹ thuật có chiều sâu, cảm giác rất thích
    • Được tạm thoát khỏi nỗi sợ hãi (FUD) liên quan đến AI nên thấy nhẹ nhõm. Trước đây mở HN không thấy lo lắng, nhưng dạo gần đây toàn là chuyện “mọi thứ sắp toang rồi”
    • Nhìn bề ngoài thì đây là một vấn đề kỹ thuật nhỏ, nhưng thực ra là quyết định lớn ảnh hưởng đến kiến trúc ngôn ngữ Go và định hướng lãnh đạo
      Những người theo chủ nghĩa hoàn hảo, lập trình viên thực chiến và cộng đồng crypto đều có lập trường khác nhau
      Tài liệu liên quan: RFC 9562
      Tôi mong Go sẽ đưa ra quyết định đúng. Đặc biệt TinyGo thực sự rất tuyệt cho vi điều khiển
    • Bức tranh về những người ghét Go khá thú vị. Giờ là thời đại AI đọc code, nên có cảm giác niềm vui chê bai ngôn ngữ cũng không còn nữa
  • Tôi không quá quan tâm việc Go hỗ trợ tạo UUID, nhưng việc có kiểu UUID tiêu chuẩn thì thực sự quan trọng
    Nó sẽ cho phép marshal nhất quán trong JSON, Text, database/sql, v.v.
    Trong một phân tích phụ thuộc Go gần đây, google/uuid là package được dùng nhiều thứ hai
    Phân tích liên quan: The most popular Go dependency

    • Tôi cũng muốn kiểu dec128 được đưa vào chuẩn. Lý tưởng nhất là cung cấp dưới dạng struct có thể dễ dàng chuyển sang uint128
  • Sức hấp dẫn của Go nằm ở tính thực dụng hơn là các tính năng hào nhoáng
    Ngôn ngữ không trở nên phức tạp đến mức sụp đổ, mà chỉ thêm những gì cần thiết

    • Gần đây tôi cũng nâng cấp, bỏ qua khá nhiều phiên bản mà không gặp vấn đề gì
      Nhờ cam kết tương thích nên có thể yên tâm sử dụng. Đây là ngôn ngữ thay đổi chậm nhưng cải thiện đều đặn
  • So với việc package uuid của Google không còn hoạt động mạnh, tôi nghĩ điều quan trọng hơn là gofrs/uuid đang tuân theo tiêu chuẩn mới và được duy trì tích cực
    Kho lưu trữ gofrs/uuid

    • Tôi thích làm thư viện không có phụ thuộc bên ngoài. Thay đổi lần này giúp công việc đó dễ hơn
    • Tuy vậy google/uuid không có bản phát hành nào sau năm 2024, và đến tháng 6 năm 2025 vẫn còn issue liên quan được mở
      Issue #194
    • Đề xuất này đã được thảo luận từ 3 năm trước
  • Tôi thực sự ghét UUID. Đây là loại định danh không thân thiện với con người
    Khi debug hoặc xem kết quả truy vấn, nó quá dài và bất tiện.
    Dĩ nhiên nó hữu ích khi cần ID duy nhất giữa các hệ thống tách biệt hoàn toàn, nhưng phần lớn trường hợp là bị lạm dụng
    Trong các trường hợp thông thường, bộ cấp số tập trung tốt hơn nhiều.
    Ví dụ, một thủ tục như GetNextId trong DB sẽ thân thiện và hiệu quả hơn

    • Trước đây ở công ty tôi quản lý dự án bằng mã 6 chữ số, rồi có người đổi nó sang UUID
      Kết quả là nó trở thành mã mà con người không thể đọc được, thậm chí còn là bản tự triển khai nên lại có tính tuần tự kỳ lạ. Một quyết định tệ hại hoàn toàn
    • Thực ra trong phần lớn trường hợp, bộ đếm số nguyên là đủ
      Với Postgres, dùng bảng bộ đếm có thể tạo hàng chục nghìn ID mỗi giây
      Cách này còn giúp tiết kiệm bộ nhớ, tăng hiệu quả nén và hiệu năng hashmap
      UUID thì tiện nhưng phá hỏng hiệu năng
    • Tôi ước gì nó có yếu tố gì đó dễ đọc với con người
      Ví dụ: dạng như BASKETBALL-...-FISH gắn thêm checksum dựa trên từ ngữ thì sẽ dễ nhớ hơn
    • Có nhắc đến “ngẫu nhiên hóa có tính xác định”, và tôi cũng nghĩ cách như LFSR (thanh ghi dịch phản hồi tuyến tính) là ổn
  • Tôi từng thắc mắc liệu UUID có thật sự sẽ được thêm vào Go hay không

    • Hiện đang ở trạng thái ‘Likely accept’. Có thể kiểm tra trên bảng dự án Go
      Nếu không có phản đối đặc biệt nào, khả năng cao là sẽ được đưa vào
    • Đúng vậy, dự kiến sẽ được thêm
  • Kotlin cũng недавно thêm hỗ trợ các phiên bản UUID dựa trên RFC 9562 vào thư viện chuẩn trong phiên bản 2.3
    Hỗ trợ cả JVM, JS, WASM và Native.
    Khi RFC của IETF đã ổn định, việc Go làm theo là hợp lý

  • Việc Go thiếu hỗ trợ cho những chức năng cơ bản như thế này khá đáng tiếc

    • Tôi tò mò ngôn ngữ nào đã chuẩn hóa chuyện này tốt hơn. Có lẽ là Java chăng? Python hay Rust cũng ở tình trạng tương tự
    • Ý nghĩa của “kèm pin sẵn” đã thay đổi rất nhiều trong 20 năm qua. Có lẽ đây là chức năng mà bên trong Google không cần đến
    • UUID rốt cuộc cũng chỉ là mảng 16 byte. Việc tạo v4 chỉ cần vài dòng. Không phải chuyện lớn
    • Tôi tò mò bạn thấy đang thiếu chức năng nào
      Cá nhân tôi thấy hệ thống logging của Go quá đơn giản nên phải tự làm
      Mô-đun slog thì chậm và bất tiện. Có vẻ như chỉ nghĩ đến môi trường enterprise
    • Dù vậy, chất lượng thư viện chuẩn của Go vẫn thuộc hàng tốt nhất. Tôi nghĩ đó là stdlib được dùng nhiều nhất trong công việc hằng ngày
  • Tôi từng nghĩ xem có cách nào để vừa có hiệu quả gom cụm DB của v7 vừa có tính ngẫu nhiên của v4 hay không
    Có vẻ nếu dùng v7 ở bên trong, rồi xáo trộn bằng XOR hoặc AES trước khi gửi ra ngoài thì sẽ làm được

    • Thực tế đã có thử nghiệm như vậy: dự án uuidv47
    • Nếu mục tiêu là quyền riêng tư, tôi nghĩ mã hóa khóa số nguyên sẽ tốt hơn
      Ví dụ dùng mã hóa Feistel thì có thể tạo public ID dạng opaque mà không gặp vấn đề hiệu năng của UUID