회원 테이블의 PK를 1, 2, 3 같은 자동 증가 숫자로 두면 URL에 /user/1, /user/2가 노출된다. 누군가 숫자를 바꿔가며 다른 회원 정보에 접근을 시도할 수 있다. 이런 상황에서 UUID를 쓰면 ID를 추측하는 게 사실상 불가능해진다.
UUID 구조와 버전
UUID는 128비트(16바이트) 길이의 식별자다. 보통 하이픈으로 구분된 32자리 16진수 문자열로 표현한다.
550e8400-e29b-41d4-a716-446655440000
여러 버전이 있지만 실무에서 가장 많이 쓰이는 건 v4다. v4는 완전 랜덤 기반으로, 타임스탬프나 MAC 주소 같은 외부 정보에 의존하지 않는다.
충돌 확률은 얼마나 되나
UUID v4의 랜덤 비트 수는 122비트다. 충돌이 50% 확률로 발생하려면 약 2.71 × 10^18개를 생성해야 한다. 매초 10억 개씩 생성해도 약 86년이 걸린다. 현실적으로 충돌 걱정은 할 필요가 없다.
자동 증가 ID 대신 UUID를 쓰는 이유
| 항목 | 자동 증가 (INT) | UUID v4 |
|---|---|---|
| 예측 가능성 | 다음 ID 추측 가능 | 추측 불가 |
| 분산 생성 | 단일 DB 의존 | 어디서든 독립 생성 |
| 저장 크기 | 4~8바이트 | 16바이트 |
| 인덱스 성능 | 순차적이라 좋음 | 랜덤이라 다소 불리 |
| 보안 | 열거 공격 취약 | 안전 |
마이크로서비스처럼 여러 서버에서 동시에 ID를 생성해야 하는 환경에서는 UUID가 특히 유리하다. 중앙 DB에 의존하지 않고 각 서비스가 독립적으로 고유 ID를 만들 수 있기 때문이다.
UUID 빠르게 만들기
개발 중에 테스트 데이터용 UUID가 여러 개 필요하거나, DB 마이그레이션 스크립트에 넣을 값이 필요할 때 UUID 생성기에서 한 번에 최대 1,000개까지 생성할 수 있다. 하이픈 제거, 대문자 변환, 중괄호 감싸기, URN 형식 등 포맷 옵션도 있어서 시스템 요구 사항에 맞춰 뽑을 수 있다. 결과를 텍스트 파일로 다운로드하는 기능도 있으니 대량 데이터 입력 시 유용하다.
TIP MySQL에서 UUID를 PK로 쓸 때는 BINARY(16) 타입에 UUID_TO_BIN() 함수로 저장하면 인덱스 성능 저하를 줄일 수 있다. 문자열(CHAR(36))로 저장하는 것보다 공간도 절약된다.