Trình tạo UUID v7

Tạo UUID v7 theo thứ tự thời gian cho khóa chính cơ sở dữ liệu

Định dạng

Số lượng:

UUID v7 là gì?

UUID v7 là định dạng UUID thế hệ tiếp theo được chuẩn hóa trong RFC 9562 (tháng 5 năm 2024). UUID v7 mã hóa timestamp Unix 48-bit vào các bit có ý nghĩa nhất, tiếp theo là các dấu phiên bản và biến thể, và điền các bit còn lại với dữ liệu ngẫu nhiên an toàn về mặt mật mã.

Vì timestamp chiếm các bit cao, các giá trị UUID v7 được sắp xếp theo trình tự thời gian. Điều này làm cho chúng phù hợp tuyệt vời cho các khóa chính database, nơi UUID ngẫu nhiên (v4) gây ra phân mảnh chỉ mục B-tree.

Tại sao UUID Ngẫu nhiên Phân mảnh Chỉ mục Database

Chỉ mục B-tree — được sử dụng bởi PostgreSQL, MySQL, SQLite, và hầu hết các database khác — giữ các hàng được sắp xếp theo giá trị khóa.

Với UUID v4 (hoàn toàn ngẫu nhiên), mỗi lần chèn mới rơi vào một vị trí về cơ bản ngẫu nhiên trong cây chỉ mục. Điều này buộc database phải đọc và ghi lại các trang chỉ mục nội bộ liên tục.

Bố cục Bit UUID v7

UUID v7 rộng 128 bit, được chia thành sáu trường:

BitTrườngMục đích
48unix_ts_msTimestamp Unix 48-bit tính bằng mili giây — chiếm toàn bộ nửa cao
4verSố phiên bản — luôn là 0111 (thập phân 7)
12rand_a12 bit dữ liệu ngẫu nhiên an toàn về mặt mật mã
2varDấu biến thể — luôn là 10 (biến thể RFC 4122)
62rand_b62 bit dữ liệu ngẫu nhiên an toàn về mặt mật mã

Độ chính xác timestamp là 1 mili giây. Trong cùng một mili giây, các giá trị UUID v7 được sắp xếp theo hậu tố ngẫu nhiên của chúng.

UUID v7 so với UUID v1

UUID v1 và UUID v7 đều nhúng timestamp, nhưng khác nhau đáng kể về thiết kế:

Tính năngUUID v7UUID v1
Epoch / Cơ sở Thời gianEpoch Unix (1 tháng 1 năm 1970)Epoch Gregorian (15 tháng 10 năm 1582)
Độ chính xác Thời gian1 mili giây100 nano giây
Có thể Sắp xếpCó — k-sortable theo thiết kếKhông — các trường thời gian bị xáo trộn trong bố cục UUID
Quyền riêng tưKhông rò rỉ thông tin máy chủNhúng địa chỉ MAC của máy chủ tạo
Hiệu suất Chỉ mục DBXuất sắc — chèn tuần tự, phân mảnh tối thiểuKém — không tuần tự dù có timestamp
Tiêu chuẩnRFC 9562 (2024)RFC 4122 (2005)
Hỗ trợ Trình duyệt GốcChưa (không có crypto.randomUUID v7)Không có sẵn gốc

Đối với bất kỳ dự án mới nào cần UUID theo thứ tự thời gian, hãy ưu tiên UUID v7 hơn UUID v1.

UUID v7 so với ULID

ULID (Universally Unique Lexicographically Sortable Identifier) giải quyết vấn đề tương tự như UUID v7:

UUID v7
  • Tuân theo tiêu chuẩn UUID RFC 9562 — tương thích với tất cả công cụ UUID
  • Định dạng hex có gạch nối — được nhận dạng toàn cầu
  • Hỗ trợ cột UUID database gốc
  • 128 bit tổng cộng
ULID
  • Mã hóa Crockford Base32 — 26 ký tự, nhỏ gọn hơn một chút
  • Không phân biệt chữ hoa chữ thường và tránh các ký tự mơ hồ (I, L, O, U)
  • Dễ đọc hơn với con người nhìn thoáng qua
  • Yêu cầu thư viện — không có hỗ trợ nền tảng gốc

Nếu bạn đã trong hệ sinh thái UUID (cột uuid PostgreSQL, REST API), hãy sử dụng UUID v7. Nếu bắt đầu mới và thích mã hóa thân thiện với con người hơn, ULID là lựa chọn thay thế hợp lý.

Sử dụng UUID v7 trong Database

UUID v7 chưa được hầu hết các database tạo ra nội bộ, nhưng có thể được lưu trong các cột UUID tiêu chuẩn:

PostgreSQL
PostgreSQL: lưu trong cột uuid. Tiện ích mở rộng pg-uuidv7 thêm hàm phía server uuid_generate_v7().
MySQL / MariaDB
MySQL / MariaDB: lưu trong cột BINARY(16) hoặc CHAR(36). Tạo trong mã ứng dụng.
SQLite
SQLite: lưu dưới dạng TEXT (36 ký tự) hoặc BLOB (16 byte). Tạo trong mã ứng dụng.

Ví dụ Mã

UUID v7 chưa có sẵn qua crypto.randomUUID(). Sử dụng thư viện như uuidv7 (npm) cho đến khi có hỗ trợ gốc:

JavaScript (browser / Node.js 20+)
function generateUuidV7() {
  const buf = new Uint8Array(16)
  crypto.getRandomValues(buf)

  const ms = BigInt(Date.now())

  // Embed 48-bit Unix ms timestamp
  buf[0] = Number((ms >> 40n) & 0xFFn)
  buf[1] = Number((ms >> 32n) & 0xFFn)
  buf[2] = Number((ms >> 24n) & 0xFFn)
  buf[3] = Number((ms >> 16n) & 0xFFn)
  buf[4] = Number((ms >> 8n)  & 0xFFn)
  buf[5] = Number(ms & 0xFFn)

  // Set version 7 (0111xxxx)
  buf[6] = (buf[6] & 0x0F) | 0x70

  // Set variant (10xxxxxx)
  buf[8] = (buf[8] & 0x3F) | 0x80

  const hex = [...buf].map(b => b.toString(16).padStart(2, '0')).join('')
  return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`
}

// Node.js 20+ built-in
// import { randomUUID } from 'node:crypto'  // v4 only — no v7 yet in stdlib
Python (uuid7 library)
# pip install uuid7
import uuid_extensions

uid = uuid_extensions.uuid7()
print(uid)                       # e.g. 018e2b3d-1a2b-7000-8000-abc123456789
print(uid.time)                  # Unix ms timestamp embedded in the UUID

# Or as a plain string
from uuid_extensions import uuid7str
print(uuid7str())
PostgreSQL — generate UUID v7
-- PostgreSQL 13+ extension-free implementation
CREATE OR REPLACE FUNCTION uuid_generate_v7()
RETURNS uuid
LANGUAGE sql
AS $$
  SELECT encode(
    set_bit(
      set_bit(
        overlay(
          uuid_send(gen_random_uuid())
          PLACING substring(int8send(floor(extract(epoch FROM clock_timestamp()) * 1000)::bigint) FROM 3)
          FROM 1 FOR 6
        ),
        52, 1
      ),
      53, 1
    ),
    'hex'
  )::uuid;
$$;

-- Usage as a default primary key
CREATE TABLE events (
  id uuid PRIMARY KEY DEFAULT uuid_generate_v7(),
  payload jsonb,
  created_at timestamptz DEFAULT now()
);
TypeScript — extract timestamp from UUID v7
function extractTimestamp(uuid: string): Date {
  const hex = uuid.replace(/-/g, '')
  const ms = parseInt(hex.slice(0, 12), 16)  // first 48 bits = ms timestamp
  return new Date(ms)
}

const uid = '018e2b3d-1a2b-7000-8000-abc123456789'
console.log(extractTimestamp(uid).toISOString())
// → "2024-03-15T10:22:05.259Z"

Câu hỏi Thường gặp

UUID v7 có tương thích ngược với UUID v4 không?
Có. UUID v7 sử dụng cùng định dạng wire 128-bit, 32-chữ-số-hex, có gạch nối như tất cả các phiên bản UUID khác.
UUID v7 có lộ timestamp tạo không?
Có — 48 bit đầu tiên là timestamp Unix mili giây, vì vậy bất kỳ ai có UUID đều có thể xác định gần đúng thời điểm tạo.
Tôi có thể sử dụng UUID v7 làm khóa chính database mà không cần cột created_at riêng không?
Có. Vì UUID v7 nhúng timestamp độ chính xác mili giây, bạn có thể giải mã giá trị đó để lấy thời gian tạo gần đúng.
UUID v7 có bao nhiêu entropy?
UUID v7 có 74 bit dữ liệu ngẫu nhiên (12 bit ở rand_a + 62 bit ở rand_b). Ít hơn một chút so với 122 bit của UUID v4.
UUID v7 có được hỗ trợ gốc trong trình duyệt hoặc Node.js không?
Chưa tính đến đầu năm 2025. Tiêu chuẩn RFC 9562 được công bố vào tháng 5 năm 2024 và hỗ trợ nền tảng vẫn đang theo kịp. Sử dụng gói npm uuidv7 cho đến nay.