PK 전략 중 UUID를 중심으로
2025-07-07
해당 Post는 사이드 프로젝트를 진행하다가 UUID에 관해 조금 더 찾아본 내용들을 정리해보는 글입니다.
분산 시스템에서 Primary Key(PK) 생성 전략들 중 UUID를 중심으로 장단점과 실무 활용 방안을 정리합니다.
1. 문제 인식: 문제 인식: GenerationType.IDENTITY의 한계
AUTO_INCREMENT
와 같은 전통적 PK 생성 방식은 단일 데이터베이스 환경에서는 효과적이지만, 분산 시스템에서는 다음과 같은 한계를 드러냅니다:
- 충돌 위험: 샤딩 또는 복제 환경에서 각 노드가 동일한 PK(예: 1, 2, 3…)를 생성하여 충돌 발생.
- 보안 취약성: 순차적 PK는 데이터 개수 추정이나 URL 조작(예:
/user/123
)을 통한 공격에 취약. - 확장성 제약: 중앙화된 키 생성은 병목을 유발하며, 동기화 로직이 필요.
- 저장 공간 고갈:
INT
(4바이트) 또는BIGINT
(8바이트)의 범위 제한으로 대규모 시스템에서 고갈 위험. - 예측 가능성: 순차적 값은 다음 PK를 쉽게 예측 가능, 보안 및 프라이버시 문제 야기.
2. JPA의 GenerationType 비교
JPA는 다양한 PK 생성 전략을 제공합니다.
각 전략의 특성은 다음과 같습니다:
전략 | 설명 | 장점 | 단점 |
---|---|---|---|
TABLE | 별도 테이블에서 키 관리 | 모든 DB와 호환 | 동시성 병목, 성능 저하 |
SEQUENCE | DB의 SEQUENCE 객체 사용 | 고성능, 효율적 | 특정 DB(예: PostgreSQL, Oracle)에 의존 |
IDENTITY | DB의 AUTO_INCREMENT 사용 | 구현 간단, DB가 키 생성 | 분산 환경에서 충돌 위험 |
UUID | 128비트 고유 식별자 사용 | 충돌 가능성 극히 낮음, 확장성 우수 | 인덱스 성능 저하, 저장 공간 큼 |
AUTO | JPA가 DB 특성에 맞춰 전략 선택 | 유연성, DB 독립적 | 일관성 부족, 예측 불가 |
3. UUID란?
UUID(Universally Unique Identifier)는 128비트(16바이트)로 구성된 고유 식별자로,
분산 환경에서 충돌 가능성이 극히 낮습니다(RFC 4122 준수).
-
형식:
550e8400-e29b-41d4-a716-446655440000
(36자리 문자열, 하이픈 포함). -
구조:
550e8400 | e29b | 41d4 | a716 | 446655440000 |
---|---|---|---|---|
8자리 | 4자리 | 4자리 | 4자리 | 12자리 |
time_low | time_mid | time_hi_and_version | clock_seq | node |
- 버전:
- v1: 시간과 MAC 주소 기반, 고유하지만 MAC 주소 노출로 보안 취약.
- v4: 난수 기반, 가장 널리 사용, 충돌 확률 2^128로 사실상 0. - 제일 많이 쓰인다고 합니다.
- v7: 시간순 정렬 가능, 최신 표준(2022), 고성능 요구 시스템에 적합.
- 자바 생성 예시 (v4):
import java.util.UUID; UUID uuid = UUID.randomUUID(); System.out.println(uuid); // 예: 550e8400-e29b-41d4-a716-446655440000
4. UUID의 장점
- 전역 고유성: 중앙 서버 없이 독립적으로 고유 키 생성.
- 확장성: 노드 간 동기화 없이 대규모 분산 시스템 지원.
- 표준화: RFC 4122 기반으로 모든 언어와 플랫폼에서 지원.
- 보안성: 예측 불가능한 난수로 외부 노출 시 안전.
- 분산 환경 최적화: 동시 생성 시 충돌 가능성 없음.
5. UUID의 단점
- 인덱스 성능 저하: 랜덤 값으로 B+ Tree 인덱스 단편화, 삽입/검색 성능 저하(정수형 PK 대비 2~3배 느림).
- 저장 공간: 16바이트로
INT
(4바이트),BIGINT
(8바이트)보다 큼. - 정렬 불가: v4는 시간 정보 없음, 범위 쿼리 및 시간순 정렬 불리.
- 클러스터형 인덱스 문제: MySQL InnoDB와 같은 엔진에서 무작위 삽입으로 페이지 분할, I/O 부담 증가.
6. UUID와 대안 비교
방식 | 고유성 | 인덱싱 효율 | 저장 공간 | 정렬 가능 | 분산 환경 적합성 | 비고 |
---|---|---|---|---|---|---|
UUID v4 | 높음 | 낮음 | 큼(16B) | 불가 | 높음 | 표준, 보안성 높음 |
UUID v7 | 높음 | 중간 | 큼(16B) | 가능 | 높음 | 시간순 정렬 가능 |
Auto Increment | 낮음 | 높음 | 작음(4~8B) | 가능 | 낮음 | 단일 DB 적합 |
Snowflake 등 | 높음 | 높음 | 중간(8B) | 가능 | 높음 | Twitter 개발, 대용량 적합 |
7. 실무 활용 사례
- 외부 식별자: 공개 API, URL, 토큰 등 외부 노출 시 UUID 사용.
- 마이크로서비스: 각 서비스가 독립적으로 UUID 생성, 중앙 DB 의존성 제거.
- 이벤트 소싱: 이벤트 ID로 UUID 사용하여 시간순 정렬 불필요 시 최적.
8. 결론
UUID는 분산 시스템에서 고유성과 확장성을 보장하는 강력한 PK 생성 전략입니다.
그러나 인덱스 성능과 저장 공간 문제를 고려해 v7, 바이너리 저장, 하이브리드 전략 등을 활용해야 합니다.
시스템의 규모, 성능 요구사항, 보안 필요성에 따라 UUID와 대안(Snowflake, Auto Increment)을 신중히 선택하는 것이 중요합니다.