Almanac of UUIDs · Part VIII
Implementation and Migration
8.1 PostgreSQL 18+ Implementation
PostgreSQL is at the forefront of adopting RFC 9562. Version 18 is slated to include native functions.
-- Generating a v7 UUID (Native PG 18+)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuidv7(),
name TEXT
);
-- Extracting Timestamp from v7
SELECT uuid_extract_timestamp(id) FROM users;For older PostgreSQL versions (16/17), extensions like pg_uuidv7 or PL/pgSQL functions can be used to generate the byte sequence manually using clock_timestamp().
8.2 Live Migration Strategy (v4 to v7)
Migrating a live database from v4 to v7 is high-impact but feasible.
- Dual Support: Ensure application logic can read both formats (they are both 128-bit UUIDs, so no schema change is needed for the data type).
- Default Change: Alter the table to change the default generation function.
ALTER TABLE orders ALTER COLUMN id SET DEFAULT uuidv7(); - The "Right-Append" Effect: Existing v4 data will remain fragmented. However, all new inserts will begin appending sequentially to the right side of the B-Tree. Over time, the active working set of the index becomes efficient.
Caution
Do not attempt to rewrite existing v4 rows to v7 unless necessary. Changing Primary Key values requires updating all Foreign Keys in dependent tables, which causes massive locking and downtime.
8.3 Regex Validation
Validating UUIDs, particularly distinguishing between versions, is critical for data integrity.
Strict UUIDv7 Regex
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$General UUID (All Versions) Regex
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$