UUID란 무엇이고 왜 쓰는가
데이터베이스에서 행을 구분하는 가장 익숙한 방법은 1, 2, 3처럼 번호를 하나씩 늘려 가는 것입니다. 이 방식은 번호를 나눠 주는 주체가 하나일 때만 성립합니다. 서버가 여러 대이거나, 마이크로서비스가 각자 데이터를 만들거나, 기기가 오프라인 상태에서 먼저 저장하고 나중에 동기화하는 구조에서는 누가 다음 번호인지 물어볼 상대가 없습니다.
UUID는 이 문제를 조율이 아니라 크기로 해결합니다. 128비트짜리 값을 쓰되 서로 겹칠 확률이 무시할 만큼 작게 만들어, 아무와도 상의하지 않고 각자 만들어도 부딪히지 않게 하는 것입니다. 마이크로소프트 계열에서 쓰는 GUID도 같은 표준을 부르는 다른 이름이며, 실무에서는 같은 것으로 봐도 무방합니다. 규격은 RFC 4122에 정의되어 있고 2024년의 RFC 9562가 이를 갱신했습니다.
생김새 뜯어보기
f47ac10b-58cc-4372-a567-0e02b2c3d479 같은 값은 언뜻 아무 글자나 늘어놓은 것처럼 보이지만 자리마다 뜻이 정해져 있습니다. 16진수 32자리를 하이픈으로 8-4-4-4-12 로 끊은 형태이고, 세 번째 묶음의 첫 글자가 버전 번호입니다. 위 예시에서 4372의 4가 버전 4라는 표시입니다.
네 번째 묶음의 첫 글자는 변형(variant)을 나타내며 보통 8, 9, a, b 중 하나가 옵니다. 즉 무작위로 보이는 값이라도 이 두 자리는 자유롭게 정해지지 않습니다. 직접 만든 문자열이 UUID로 취급되지 않는다면 대개 이 두 자리가 규격에 맞지 않는 경우입니다.
버전마다 다른 성질
| 버전 | 만드는 방식 | 고려할 점 |
|---|---|---|
| v1 | 시각 + 기기의 MAC 주소 | 정렬은 잘 되지만 생성한 기기와 시각이 값에 그대로 드러납니다 |
| v4 | 난수 122비트 | 가장 널리 쓰입니다. 아무 정보도 흘리지 않는 대신 정렬 순서가 없습니다 |
| v7 | 밀리초 시각 + 난수 | 시간순으로 정렬됩니다. 색인 단편화를 줄이려는 최근 표준입니다 |
이 도구가 만드는 값은 v4입니다. 식별자에서 아무것도 유추할 수 없어야 하는 용도, 즉 세션 토큰이나 외부에 노출되는 리소스 주소에는 v4가 맞습니다.
정말 겹치지 않는가
v4는 122비트가 난수이므로 경우의 수가 약 5.3 × 1036입니다. 생일 문제로 계산하면 충돌 확률이 10억 분의 1에 이르려면 대략 103조 개를 만들어야 합니다. 초당 10억 개씩 만들어도 사람이 살아 있는 동안 도달할 수 없는 규모입니다.
다만 이 계산은 난수가 정말 고르게 나온다는 전제 위에 있습니다. Math.random() 같은 의사난수로 UUID를 조립하면 경우의 수는 그대로여도 실제로 나오는 값의 폭이 훨씬 좁아집니다. 이 도구가 브라우저의 crypto.randomUUID()와 Web Crypto API를 쓰는 이유가 그것입니다.
기본 키로 쓸 때 생각할 것
- 색인 단편화. v4는 순서가 없어서 새 행이 B-트리 색인의 아무 곳에나 들어갑니다. 쓰기가 많은 표에서는 페이지 분할이 잦아지고 캐시 적중률이 떨어집니다. 시간순 정렬이 필요하면 v7을 쓰거나 별도의 정렬용 열을 두는 편이 낫습니다.
- 저장 크기. 36자 문자열로 저장하면 한 행에 36바이트가 들지만, 16바이트 이진값으로 저장하면 절반 이하입니다. PostgreSQL의
uuid타입이나 MySQL의BINARY(16)을 쓰면 색인 크기도 함께 줄어듭니다. - 노출. 순번 키를 URL에 쓰면 전체 건수와 생성 순서가 그대로 드러납니다. UUID는 그 문제가 없지만, 반대로 값 자체가 접근 권한이 되지는 않습니다. 추측하기 어렵다는 것과 인가는 다른 문제입니다.
UUID가 답이 아닌 경우
사람이 읽고 불러 줘야 하는 번호에는 맞지 않습니다. 주문 번호나 문의 번호를 전화로 불러 주는 상황이라면 36자리 16진수보다 짧은 영숫자 코드가 낫습니다. 인쇄물이나 명세서에 들어가는 참조 번호도 마찬가지입니다.
보안 토큰으로 쓸 때도 한 가지 유의할 점이 있습니다. v4의 무작위 비트는 122비트라서 그 자체로는 충분히 강하지만, 값이 로그나 리퍼러 헤더에 남는 자리에 쓰면 강도와 무관하게 새어 나갑니다. 유효 기간과 폐기 절차가 함께 있어야 합니다.