UUID 가이드: v4와 v7의 차이, 데이터베이스 기본 키로 쓸 때 주의할 점
550e8400-e29b-41d4-a716-446655440000 같은 문자열은 주문 번호, 파일 이름, API 요청 ID 등 곳곳에 쓰입니다. UUID가 어떻게 만들어지고, 어떤 버전을 골라야 하는지 알아봅니다.
UUID란 무엇인가
UUID(Universally Unique Identifier)는 128비트 크기의 식별자로, 중앙 서버에 번호를 물어보지 않고도 전 세계 어디서든 겹치지 않는 ID를 만들 수 있게 해 줍니다. 마이크로소프트 계열에서는 GUID라고도 부릅니다. 최신 표준은 2024년에 발표된 RFC 9562입니다.
표기는 16진수 32글자를 8-4-4-4-12 형태로 하이픈으로 나눈 36글자입니다. 세 번째 묶음의 첫 글자가 버전을 나타내므로, 예를 들어 xxxxxxxx-xxxx-4xxx-...이면 v4, 7xxx이면 v7입니다.
버전별 차이
일상적인 용도라면 v4, 데이터베이스 기본 키처럼 정렬과 삽입 성능이 중요하면 v7을 고르는 것이 요즘의 일반적인 선택입니다.
- v1: 생성 시각과 장비의 MAC 주소를 조합합니다. 시간 순서는 있지만 장비 정보가 노출될 수 있습니다.
- v3, v5: 네임스페이스와 이름을 해시해서 만듭니다. 같은 입력이면 항상 같은 UUID가 나와 '결정적 ID'가 필요할 때 씁니다(v3는 MD5, v5는 SHA-1).
- v4: 122비트가 무작위입니다. 가장 널리 쓰이며 구현이 간단합니다.
- v7: 앞 48비트에 밀리초 단위 유닉스 시간을, 나머지에 무작위 값을 넣습니다. 생성 순서대로 정렬됩니다.
정말 중복되지 않을까
v4 UUID의 무작위 부분은 122비트로, 가능한 값은 약 5.3 × 10^36개입니다. 생일 문제로 계산하면 중복 확률이 50%에 이르려면 약 2.7 × 10^18개, 즉 매초 10억 개씩 85년 가까이 만들어야 합니다. 실무에서는 사실상 중복이 없다고 봐도 됩니다.
다만 이 계산은 난수가 제대로 무작위일 때만 성립합니다. 가상 머신 복제 직후 난수 생성기 상태가 같아지거나, 예측 가능한 난수 함수로 직접 구현한 경우 실제로 중복 사고가 보고된 적이 있습니다. 표준 라이브러리의 UUID 함수를 쓰는 것이 가장 안전합니다.
데이터베이스 기본 키로 쓸 때
UUID를 기본 키로 쓰면 여러 서버에서 동시에 ID를 만들 수 있고, URL에 넣어도 전체 데이터 개수나 순서를 추측당하지 않는다는 장점이 있습니다. 자동 증가 정수(1, 2, 3...)를 쓰면 /orders/1052 같은 주소에서 경쟁사가 주문 수를 짐작할 수도 있습니다.
단점은 크기와 순서입니다. UUID는 16바이트로 8바이트 정수의 두 배이며, 문자열(36글자)로 저장하면 더 커집니다. 또 v4는 완전히 무작위라서 B-트리 인덱스의 아무 곳에나 삽입되어 페이지 분할이 잦아지고 쓰기 성능이 떨어집니다. v7은 시간 순으로 증가하므로 이 문제를 크게 줄여 줍니다.
- PostgreSQL: uuid 타입(16바이트)을 사용합니다.
- MySQL: BINARY(16)으로 저장하고, 8.0 이상에서는 UUID_TO_BIN 함수를 활용합니다.
- SQL Server: uniqueidentifier 타입을 사용합니다.
UUID를 비밀 값으로 쓰면 안 되는 경우
UUID는 '겹치지 않는 이름'이지 '추측할 수 없는 비밀'로 설계된 것이 아닙니다. v1과 v7은 생성 시각이 들어 있어 일부 비트가 예측 가능합니다. 비밀번호 재설정 토큰이나 API 시크릿처럼 보안이 중요한 값은 충분한 길이의 암호학적 난수로 만드는 것이 원칙입니다.
AIBIZAP의 UUID 생성기로 필요한 만큼 UUID를 만들 수 있고, 보안용 비밀 값이 필요하다면 클라이언트 자격 증명 생성기를 사용하세요. JSON 샘플로 테이블을 설계한다면 JSON DDL 생성기와 함께 쓰면 편리합니다.