728x90
UUID는 128비트 길이의 고유 식별자로, 중앙 관리 시스템 없이도 전 세계적으로 유일한 ID를 생성할 수 있도록 설계되었습니다.
RFC 4122 표준으로 정의되어 있으며, 일반적으로 다음과 같은 형태로 표현됩니다
`550e8400-e29b-41d4-a716-446655440000`
8-4-4-4-12 형식의 16진수로 구성되며, 하이픈으로 구분된 5개의 그룹으로 이루어집니다.
UUID의 구조
UUID는 총 128비트(16바이트)로 구성되며, 다음과 같이 분해할 수 있습니다.
`xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`
- time_low (32비트): 타임스탬프의 하위 32비트
- time_mid (16비트): 타임스탬프의 중간 16비트
- time_hi_and_version (16비트): 타임스탬프의 상위 12비트와 버전 4비트
- clock_seq_and_reserved (8비트): 클럭 시퀀스 6비트와 변형 2비트
- node (48비트): 노드 식별자 (보통 MAC 주소)
여기서 M은 UUID 버전을 나타내고, N은 variant를 나타냅니다.
UUID 버전
UUID는 여러 버전이 있으며, 각각 다른 생성 방식을 사용합니다.
UUID v1 (타임스탬프 기반)
- 생성 방식: MAC 주소 + 타임스탬프 + 클럭 시퀀스
- 장점: 시간 순서대로 정렬 가능
- 단점: MAC 주소 노출로 인해 보안 문제, 생성 시간 유추 가능
import uuid
id_v1 = uuid.uuid1()
print(id_v1)
# 6ba7b810-9dad-11d1-80b4-00c04fd430c8
UUID v3 (MD5 해시 기반)
- 생성 방식: 네임스페이스 + 이름을 MD5 해싱
- 장점: 동일한 입력에 대해 동일한 UUID 생성
- 단점: MD5의 보안 취약성
import uuid
namespace = uuid.NAMESPACE_DNS
name = "example.com"
id_v3 = uuid.uuid3(namespace, name)
print(id_v3)
# 9073926b-929f-31c2-abc9-fad77ae3e8eb
UUID v4 (랜덤 기반)
- 생성 방식: 무작위 또는 의사 난수
- 장점: 동일한 입력에 대해 동일한 UUID 생성
- 단점: MD5의 보안 취약성
import uuid
id_v4 = uuid.uuid4()
print(id_v4)
# 3d6f8e29-f5a2-4c3b-9e1a-7b8c9d0e1f2a
UUID v5 (SHA-1 해시 기반)
- 생성 방식: 네임스페이스 + 이름을 SHA-1 해싱
- 장점: v3보다 보안성 향상, 결정적 생성
- 단점: 시간 순서 정렬 불가
import uuid
namespace = uuid.NAMESPACE_DNS
name = "example.com"
id_v5 = uuid.uuid5(namespace, name)
print(id_v5)
# cfbff0d1-9375-5685-968c-48ce8b15ae17
UUID v7 (타임스탬프 정렬 가능)
- 생성 방식: 유닉스 타임스탬프 + 랜덤 비트
- 장점: 시간 순서 정렬 가능(데이터베이스 인덱스 성능)+ v1의 프라이버시 문제 해결
- 단점: 비교적 최신 표준 (2024년 RFC 9562)
import { randomUUID } from 'crypto';
import { v7 as uuidv7 } from 'uuid';
const id_v7 = uuidv7();
console.log(id_v7);
# 019a7c26-5633-74a8-9c96-787e35f72e22
| 버전 | 사용 사례 |
| v1 | 레거시 시스템, 타임스탬프 필요 |
| v3 | 결정적 ID 필요 (MD5 허용) |
| v4 | 범용적인 고유 ID |
| v5 | 결정적 ID 필요 (보안 중요) |
| v7 | DB 인덱싱, 시간 순서 정렬 필요 |
UUID의 장점
- 분산 환경 친환적- 중앙 서버 없이도 각 노드에서 독립적으로 고유 ID를 생성할 수 있습니다.
- 충돌 확률 극소- UUID v4의 경우, 10억 개를 생성해도 충돌 확률 0.0000001% 수준입니다.
- 이식성- 프로그래밍 언어와 플랫폼에 관계없이 동일한 형식을 사용합니다.
- 예측 불가능성- 보안이 중요한 경우 v4 또는 v7을 사용하면 다음 ID를 예측할 수 없습니다.
UUID의 단점
- 저장 공간- 문제: 128비트(16바이트)는 일반적인 정수형보다 큽니다.
- 해결: 바이너리 형태로 저장하거나, 필요시 Base64 인코딩 사 - 인덱싱 성능 (v4의 경우)- 문제: 랜덤한 값으로 인해 B-tree 인덱스에서 성능 저하
- 해결: UUID v7 또는 ULID 사용 - 가독성- 문제: 긴 문자열로 디버깅 시 불편
- 해결: 로그나 UI에서는 앞 8자만 표시
function shortUuid(uuid) {
return uuid.split('-')[0];
}
console.log(shortUuid('550e8400-e29b-41d4-a716-446655440000'));
// "550e8400"
UUID vs 다른 식별자
- vs Auto-increment ID
- UUID 장점: 분산 환경, 병합 이용
- Auto-increment 장점: 작은 크기, 빠른 인덱싱
- vs Snowflake ID
- UUID 장점: 표준화, 간단한 구현
- Snowflake 장점: 시간 순서 정렬, 더 작은 크기 (64비트)
- vs ULID (Universally Unique Lexicographically Sortable Identifier)
- UUID v7 장점: 표준, 광범위한 지원
- ULID 장점: 더 나은 가독성, Base32 인코딩
- 보안 고려사항
- v1 사용 주의: MAC 주소 노출로 인한 프라이버시 문제
- v4 권장: 예측 불가능한 랜덤 생성
- 암호학적 안정성: 보안이 중요한 경우 암호학적으로 안전한 난수 생성기 사용 확인
import secrets
import uuid
def secure_uuid4():
return uuid.UUID(bytes=secrets.token_bytes(16), version=4)
id = secure_uuid4()
print(id)
# a25bca53-39b3-4183-974a-e1baebb8502f
결론
UUID는 분산 시스템에서 고유 식별자를 생성하는 검증된 방법입니다.
각 버전의 특징을 이해하고 사용 사례에 맞게 선택한다면, 확장 가능하고 안정적인 시스템을 구축할 수 있습니다.
- 일반적인 경우: UUID v4
- 시간 순서 정렬 필요: UUID v7
- 결정적 생성 필요: UUID v5
- 래거시 호환: UUID v1
728x90
반응형
'Data Engineer' 카테고리의 다른 글
| XAMPP MySQL이 “shutdown unexpectedly” — 포트 문제인 줄 알았는데, 진짜 원인은 mysql.global_priv 손상이 원인 (해결) (0) | 2025.10.16 |
|---|---|
| CDC 파이프라인이란? 실시간 데이터 동기화의 핵심 기술 (2) | 2025.07.30 |
| Apache Airflow란? (3) | 2025.07.29 |
| Data Driven 이란? (3) | 2025.07.28 |
| 데이터 인프라 IaC 설계 철학: Monolithic vs Modular, 어떤 전략이 옳을까? (2) | 2025.07.21 |
