개념
UUID v7은 시간순으로 정렬 가능한(time-sortable) UUID임. 전체 128비트 길이와 표준 36자 형식(8-4-4-4-12)은 다른 버전과 동일하지만, 식별자 앞부분에 타임스탬프를 포함하는 것이 핵심적인 차이점임
UUID v7의 구조
UUID의 13번째 문자는 버전을 나타냄
- UUID v4: 버전을 제외한 모든 비트가 무작위 값으로 채워짐
- UUID v7: 앞 48비트가 Unix epoch 타임스탬프(밀리초 단위)로 구성되며, 그 뒤로 버전(7)과 나머지 랜덤 비트가 이어짐
구조를 분해하면 다음과 같음
0192f0c1-2345-7abc-89de-1234567890ab
0192f0c12345: 48비트 타임스탬프7: 버전 7abc: 랜덤 비트8: Variant (RFC 4122 호환)9de-1234567890ab: 나머지 랜덤 비트
이 구조 덕분에 UUID v7은 생성 순서와 정렬 순서가 거의 일치함. 나중에 생성된 ID가 사전순(lexicographical)으로 더 크므로, ID로 정렬하면 사실상 생성 시간순으로 정렬하는 효과를 냄
데이터베이스 ID로서의 장점
데이터베이스 기본 키(Primary Key) 전략에서 UUID v7은 bigint auto-increment와 UUID v4의 장점을 결합한 대안이 될 수 있음
| 특성 | Bigint Auto-Increment | UUID v4 | UUID v7 |
|---|---|---|---|
| 열거 가능성 | O (보안 위험) | X | X |
| 인덱스 지역성(Locality) | 좋음 | 나쁨 (Page Split 유발) | 좋음 (거의 단조 증가) |
- UUID v4의 단점: 값이 완전히 무작위이므로 B-Tree 인덱스에 삽입될 때 여러 페이지에 분산됨. 이는 페이지 분할(page split)과 단편화를 유발하여 쓰기 성능을 저하시킴
- UUID v7의 장점: 타임스탬프 기반으로 값이 거의 단조 증가(monotonically increasing)하므로
auto-incrementID처럼 인덱스 지역성을 높여 쓰기 성능을 유지하는 데 유리함. 동시에 뒷부분은 랜덤 값이라 ID를 추측하거나 전체 개수를 유추하기 어려워 IDOR(Insecure Direct Object References) 같은 보안 취약점을 방지할 수 있음
결과적으로 UUID v7은 ‘추측 불가능성’과 ‘인덱스 효율’이라는 두 가지 목표를 동시에 만족시켜, 특히 외부로 노출되는 식별자로 사용하기에 적합함
고려사항
- 표준화: UUID v7은 2024년 5월에 발표된 RFC 9562에 포함된 공식 표준임
- 트레이드오프: ID에 타임스탬프가 포함되므로 대략적인 생성 시각(밀리초 단위)이 노출될 수 있음. 대부분의 애플리케이션에서는 문제가 되지 않지만, 생성 시각 자체를 민감 정보로 다뤄야 한다면 UUID v4가 더 나은 선택일 수 있음
- 구현: 최신 프레임워크와 데이터베이스에서 지원이 확대되고 있음. 예를 들어 Prisma에서는
@default(uuid(7))와 같이 간단하게 사용할 수 있음
마무리
UUID v7은 타임스탬프와 랜덤 값을 결합해 정렬 가능한 특성을 갖춘 UUID임. 데이터베이스 ID로 사용할 경우, bigint의 인덱스 지역성 장점과 UUID의 추측 불가능성을 모두 확보할 수 있는 강력한 대안이 될 수 있음