UUID vs auto-increment: quick answer
Should you use a UUID as primary key? Use a UUID when IDs are created in more than one place (several services, databases, devices or offline clients), when you merge data from different sources, or when IDs are visible in URLs and shouldn't reveal how many rows you have. Stick with an auto-increment integer for small, single-database tables where compact keys and sequential inserts matter more. If you choose UUIDs, prefer UUID v7: it's time-ordered, so it avoids most of the index fragmentation that random v4 keys cause.
| Auto-increment integer | UUID v4 | UUID v7 | |
|---|---|---|---|
| Size | 4–8 bytes | 16 bytes | 16 bytes |
| Generated | By the database (one counter) | Anywhere, no coordination | Anywhere, no coordination |
| Insert order in the index | Sequential | Random (more page splits) | Roughly sequential |
| Leaks row count / creation order | Yes | No | Creation time only |
| Safe to merge across databases | No (collisions) | Yes | Yes |
Objective
Create tables using UUID (Universally Unique Identifier) as primary keys. UUIDs are ideal for distributed systems where sequential IDs could conflict across multiple sources.
UUID v4 vs v7 vs integer keys
- Auto-increment integers are compact and index-friendly, but they leak row counts, collide when you merge data from several databases, and need a central counter.
- UUID v4 (random) can be generated anywhere — app servers, devices, offline clients — with no coordination, at the cost of 16-byte keys and random index inserts.
- UUID v7 (time-ordered) keeps v4's generate-anywhere property but sorts by creation time, so new rows land at the end of the index like an integer would.
Use integers for small, single-database tables; use UUIDs when IDs are created in more than one place or exposed publicly.
Step 1: Create Table with UUID Primary Key
Create a table using UUID as the primary key.
CREATE TABLE documents (
document_id UUID PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT,
author VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Step 2: Insert Records with UUID Values
Insert records with explicit UUID values.
INSERT INTO documents (document_id, title, content, author) VALUES
('550e8400-e29b-41d4-a716-446655440001', 'Getting Started Guide', 'Welcome to our platform...', 'Documentation Team'),
('550e8400-e29b-41d4-a716-446655440002', 'API Reference', 'Complete API documentation...', 'Engineering Team'),
('550e8400-e29b-41d4-a716-446655440003', 'Best Practices', 'Recommended approaches...', 'Architecture Team');
Step 3: Query by UUID
Query records using UUID values.
SELECT document_id, title, author
FROM documents
WHERE document_id = '550e8400-e29b-41d4-a716-446655440001';
Step 4: Create User System with UUIDs
Create a complete user system using UUIDs throughout.
CREATE TABLE users (
user_id UUID PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
username VARCHAR(50) NOT NULL UNIQUE,
display_name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE user_sessions (
session_id UUID PRIMARY KEY,
user_id UUID NOT NULL,
device_info VARCHAR(255),
ip_address VARCHAR(45),
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
INSERT INTO users (user_id, email, username, display_name) VALUES
('6ba7b810-9dad-11d1-80b4-00c04fd430c8', 'alice@example.com', 'alice', 'Alice Johnson'),
('6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'bob@example.com', 'bob', 'Bob Smith'),
('6ba7b812-9dad-11d1-80b4-00c04fd430c8', 'carol@example.com', 'carol', 'Carol Williams');
INSERT INTO user_sessions (session_id, user_id, device_info, ip_address) VALUES
('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', '6ba7b810-9dad-11d1-80b4-00c04fd430c8', 'Chrome on Windows', '192.168.1.100'),
('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12', '6ba7b810-9dad-11d1-80b4-00c04fd430c8', 'Safari on iPhone', '192.168.1.101'),
('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13', '6ba7b811-9dad-11d1-80b4-00c04fd430c8', 'Firefox on Mac', '192.168.1.102');