UUID v7 개요
UUID v7은 RFC 9562에서 도입한 버전으로, 앞쪽 48비트에 밀리초 단위 Unix 시간을 넣고 나머지 74비트를 난수로 채웁니다. 그래서 사전순 정렬이 곧 생성 순서가 됩니다.
데이터베이스에서 UUID를 기본 키로 쓰면 삽입 위치가 인덱스 전체에 흩어져 페이지 분할이 잦아집니다. v7은 새 값이 항상 인덱스 끝에 붙기 때문에 이 문제가 사라지고, 동시에 v4처럼 난수성도 유지합니다.
사용 방법
- v7을 선택합니다 (이 페이지에서는 이미 선택되어 있습니다).
- 필요하면 개수를 설정합니다. 최대 1000개까지 가능합니다.
- UUID 생성을 누릅니다. 결과는 생성 순서대로 정렬되어 있습니다.
- 전체 복사나 다운로드로 SQL 삽입문에 바로 넣을 수 있습니다.
사용 사례
- 데이터베이스 기본 키. 특히 MySQL, PostgreSQL, SQL Server의 클러스터형 인덱스에 유리합니다.
- 생성 순서대로 읽어야 하는 이벤트 로그와 감사 기록.
- 정렬 가능성과 난수성을 동시에 원하는 분산 시스템의 식별자.
구조
앞 48비트가 밀리초 Unix 타임스탬프이고, 그다음 4비트가 버전 번호(7)입니다. 12비트는 추가 정밀도나 카운터로 쓰고, 나머지 62비트는 난수입니다.
UUID v7의 역할
| 옵션 | 사용 시점 |
|---|---|
v7 | 시간순 정렬과 난수를 모두 갖춘 최신 표준 |
v4 | 정렬이 필요 없다면 더 단순한 선택 |
v6 | v1과 호환되는 정렬 방식이 필요할 때 |
v1 | MAC 주소와 시계 정밀도 문제가 있습니다 |
UUID 버전 한눈에 보기
| 버전 | 정렬 가능 | 값의 출처 | 적합한 용도 |
|---|---|---|---|
| v1 | 불가능 | 타임스탬프 + MAC 주소 | v1을 계속 쓰는 기존 시스템 |
| v3 | 불가능 | 이름의 MD5 해시 | MD5를 꼭 써야 하는 결정적 식별자 |
| v4 | 불가능 | 122비트 난수 | 대부분의 일반적인 고유 식별자 |
| v5 | 불가능 | 이름의 SHA-1 해시 | 같은 이름에서 항상 같은 식별자가 필요할 때 |
| v6 | 가능 | 재배열한 타임스탬프 | 난수성과 정렬을 함께 원할 때 |
| v7 | 가능 | 밀리초 단위 Unix 시간 | 데이터베이스 기본 키와 이벤트 식별자 |
| v8 | 불가능 | 사용자 정의 비트 레이아웃 | 사내 형식과 실험적 용도 |
일곱 버전 모두 128비트이고, 모두 같은 8-4-4-4-12 표기법으로 표현합니다. 차이는 각 비트가 무엇을 담는지뿐입니다.
코드 예제
javascript
// 직접 구현하거나 라이브러리를 사용하세요
// 예: uuid v11+ / uuidv7
import { v7 as uuidv7 } from 'uuid';
const id = uuidv7();
python
# Python 3.14+
import uuid
id = str(uuid.uuid7())
java
// Java 21+ (라이브러리 필요)
// 예: com.fasterxml.uuid
var id = Generators.timeBasedEpochGenerator().generate().toString();
csharp
// .NET 9+
var id = Guid.CreateVersion7().ToString();
sql
-- PostgreSQL 18+
SELECT uuidv7();
자주 묻는 질문
v7이 v4보다 나은가요?
인덱스가 걸린 컬럼에 넣는다면 대체로 그렇습니다. v7은 새 값이 인덱스 끝에 붙어 삽입이 순차적으로 일어나고, 그만큼 페이지 분할과 캐시 미스가 줄어듭니다. 정렬이 필요 없는 값이라면 v4로도 충분합니다.
v7은 생성 시각을 노출하나요?
앞 48비트에 밀리초 타임스탬프가 그대로 들어 있으므로 누구나 생성 시각을 읽을 수 있습니다. 그 정보가 민감하다면 v4를 쓰세요.
같은 밀리초에 여러 개를 만들면 어떻게 되나요?
타임스탬프가 같아도 뒤쪽 74비트가 난수라 값은 서로 다릅니다. 정렬은 타임스탬프 수준에서만 보장되고, 같은 밀리초 안의 순서는 무작위입니다.