UUID 가이드: 버전, 포맷, 모범 사례
UUID (범용 고유 식별자)는 중앙 기관 없이 공간과 시간에 걸쳐 고유하도록 설계된 128비트 식별자입니다. 조정 없이 독립적으로 ID를 생성해야 하는 분산 시스템의 표준 선택입니다.
UUID 포맷
UUID는 하이픈으로 구분된 다섯 그룹의 32개 16진수 문자로 표시되는 128비트 숫자입니다:
550e8400-e29b-41d4-a716-446655440000
^^^^^^^^ ^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^
time-low mid hi clk node
+ver +var
- 총: 128비트 (16바이트)
- 문자열 길이: 36문자 (16진수 32 + 하이픈 4)
- 버전: 13번째 문자에 인코딩 ("hi" 니블)
- 변형: 17번째 문자에 인코딩
UUID 생성기로 즉시 UUID를 생성하세요.
UUID 버전
UUID v1: 시간 기반
현재 타임스탬프와 기기의 MAC 주소에서 생성됩니다.
// 구조: 타임스탬프 (60비트) + 클록 시퀀스 (14비트) + 노드 (48비트)
6ba7b810-9dad-11d1-80b4-00c04fd430c8
장점: 생성 시간에 따라 자연스럽게 정렬 가능, 기기별 고유성 보장. 단점: MAC 주소 노출 (프라이버시 우려), 생성 시간을 드러낼 수 있음. 사용 시기: 시간 순서가 필요하고 통제된 환경에 있을 때.
UUID v4: 무작위
암호학적으로 안전한 난수에서 생성됩니다. 가장 널리 사용되는 버전입니다.
// 122개의 무작위 비트 (6비트는 버전과 변형에 예약)
f47ac10b-58cc-4372-a567-0e02b2c3d479
장점: 단순, 정보 유출 없음, 조정 불필요. 단점: 정렬 불가, 순차적 ID보다 약간 나쁜 데이터베이스 인덱스 성능. 사용 시기: 범용 — 대부분의 애플리케이션에서 기본 선택.
UUID v7: 시간 순서 무작위 (새 표준)
최신 버전 (RFC 9562, 2024), Unix 타임스탬프와 무작위 데이터를 결합합니다.
// 구조: 타임스탬프 (48비트) + 무작위 (74비트)
018e7b50-4a00-7000-8000-000000000001
장점: 자연스럽게 시간 정렬, 뛰어난 데이터베이스 인덱스 성능, 밀리초 정밀도 외 정보 유출 없음. 단점: 더 새로움, 일부 라이브러리가 아직 미지원. 사용 시기: 시간순으로 정렬되는 고유 ID가 필요할 때 — 데이터베이스 기본 키에 이상적.
기타 버전
- UUID v3: 네임스페이스와 이름의 MD5 해시. 결정론적.
- UUID v5: 네임스페이스와 이름의 SHA-1 해시. 결정론적이며 v3보다 선호.
- UUID v6: 더 나은 정렬성을 위해 재정렬된 v1. v7에 의해 대체됨.
- Nil UUID: 모두 0 (
00000000-0000-0000-0000-000000000000). 센티넬 값으로 사용.
충돌 확률
무작위 생성된 UUID (v4) 두 개가 충돌할 확률은? 122개 무작위 비트에서:
- 10억 UUID 생성 후: 확률 ≈ 10^18분의 1
- 50% 충돌 확률에 도달: 약 2.7 × 10^18 UUID 필요
- 초당 10억 UUID 생성 시: 약 86년 소요
모든 실용적 목적에서 UUID v4 충돌은 발생하지 않습니다. 하드웨어 장애가 훨씬 더 가능성이 높습니다.
UUID vs 다른 ID 포맷
| 포맷 | 길이 | 정렬 가능 | 고유 | URL 안전 |
|---|---|---|---|---|
| UUID v4 | 36자 | 아니오 | 예 | 예 |
| UUID v7 | 36자 | 예 | 예 | 예 |
| ULID | 26자 | 예 | 예 | 예 |
| nanoid | 21자 | 아니오 | 아마도 | 예 |
| 자동 증가 | 가변 | 예 | 테이블별 | 예 |
| Snowflake ID | 18-19자 | 예 | 시스템별 | 예 |
ULID (범용 고유 사전식 정렬 가능 식별자)
ULID는 컴팩트한 대안: 48비트 타임스탬프 + 80비트 무작위, Crockford Base32 26문자로 인코딩. 생성 시간에 따라 사전식으로 정렬됩니다.
자동 증가 ID를 사용해야 할 때
순차적 ID는 단일 데이터베이스 애플리케이션에서 더 간단하고 효율적입니다. UUID가 필요한 경우:
- 여러 시스템이 독립적으로 ID를 생성할 때
- 외부 사용자에게 삽입 순서를 드러내지 않아야 할 때
- 분산 데이터베이스를 위한 병합 친화적 ID가 필요할 때
데이터베이스 성능 고려사항
무작위 UUID (v4)는 삽입이 임의 위치에서 발생하여 B-tree 인덱스 단편화를 유발합니다. 대규모 테이블에서 순차적 ID 대비 쓰기 성능이 2-5배 저하될 수 있습니다.
해결책:
- UUID v7 사용: 시간 순서 UUID가 순차적으로 삽입되어 자동 증가 성능에 맞춤
- 바이너리로 저장:
CHAR(36)대신BINARY(16)사용으로 55% 저장 공간 절약 - ULID 사용: 정렬 가능하고 UUID보다 컴팩트
-- PostgreSQL: 네이티브 UUID 타입 (16바이트, 효율적)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL
);
-- MySQL: 성능을 위해 BINARY(16)으로 저장
CREATE TABLE users (
id BINARY(16) PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
UUID 생성
커맨드 라인
# macOS/Linux
uuidgen
# Python 원라이너
python3 -c "import uuid; print(uuid.uuid4())"
JavaScript
// 내장 (Node.js 19+, 최신 브라우저)
crypto.randomUUID();
// UUID v7용 (uuid 패키지 사용)
import { v7 } from 'uuid';
const id = v7();
Python
import uuid
uuid.uuid4() # 무작위
uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com') # 이름 기반
코드 없이 빠르게 생성하려면 UUID 생성기가 브라우저에서 즉시 v4 UUID를 생성합니다.
FAQ
데이터베이스 기본 키에 UUID를 사용해야 하나요, 자동 증가 정수를 사용해야 하나요?
단일 데이터베이스 애플리케이션에서는 자동 증가 정수가 더 간단하고 빠릅니다. 분산 시스템, 마이크로서비스, 또는 데이터베이스 삽입 전에 클라이언트 측에서 ID를 생성해야 하는 경우 UUID (가급적 v7)가 더 나은 선택입니다. PostgreSQL을 사용한다면 네이티브 UUID 지원으로 성능 차이가 무시할 수 있습니다.
UUID를 보안 토큰으로 사용할 수 있나요?
UUID v4는 암호학적 소스에서 122비트의 무작위성을 사용하여 좋은 엔트로피를 제공합니다. 그러나 보안 토큰 (API 키, 세션 ID)에는 체크섬, 만료 인코딩, 접두사 식별 같은 추가 속성이 있는 전용 토큰 포맷을 사용하는 것이 좋습니다. UUID는 신원용이지 인증용이 아닙니다.
관련 리소스
- UUID 생성기 — 온라인에서 즉시 UUID 생성
- 해시 알고리즘 비교 — UUID v3과 v5 뒤의 해시 함수 이해
- JSON API 디자인 패턴 — API 응답에서 UUID 효과적으로 사용