회원 테이블의 primary key로 auto increment 대신 UUID를 쓰라는 코드 리뷰를 받았다. 550e8400-e29b-41d4-a716-446655440000 같은 문자열인데, 이걸 왜 쓰는지, 정말 겹치지 않는지 의문이 생긴다.
UUID의 구조
UUID(Universally Unique Identifier)는 128비트 길이의 식별자다. 32개의 16진수를 하이픈으로 구분해서 8-4-4-4-12 형태로 표기한다.
550e8400-e29b-41d4-a716-446655440000
^^^^^^^^ ^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^
시간(상위) 시간 버전 변형 노드(하위)
가운데 세 번째 블록의 첫 숫자가 버전을 나타낸다. 4로 시작하면 v4(랜덤 기반)다. 실무에서 가장 많이 쓰는 버전이기도 하다.
왜 겹치지 않는가
UUID v4는 122비트를 랜덤으로 채운다(나머지 6비트는 버전/변형 표시). 가능한 조합 수는 약 5.3 × 1036개다. 숫자가 너무 커서 감이 안 오는데, 이렇게 비유할 수 있다.
매초 10억 개의 UUID를 생성해도 중복이 발생할 확률이 50%가 되려면 약 85년이 걸린다. 일반적인 서비스에서 UUID 충돌을 걱정할 필요는 없다.
auto increment 대신 UUID를 쓰는 이유
- 보안
- 순번 ID는
/users/1,/users/2처럼 추측이 가능하다. UUID는 랜덤이라 다른 사용자의 리소스를 유추할 수 없다. - 분산 시스템
- 여러 서버에서 동시에 ID를 생성해도 중앙 조율 없이 충돌을 피할 수 있다. 마이크로서비스 환경에서 큰 장점이다.
- 데이터 병합
- 서로 다른 DB의 데이터를 합칠 때 ID 충돌이 없다. 순번 ID는 양쪽 DB에 id=1이 있으면 하나를 바꿔야 한다.
단점도 있다. UUID는 36글자라 저장 공간을 더 차지하고, 인덱스 성능이 순번 ID보다 떨어진다. 정렬이 중요한 테이블에서는 신중하게 판단해야 한다.
개발 중 UUID 빠르게 뽑기
테스트 데이터에 UUID를 넣어야 하는데 코드를 작성하기 귀찮을 때가 있다. 온라인 UUID 생성기에서 개수와 포맷(하이픈, 중괄호, URN 등)을 선택하면 최대 1,000개까지 한 번에 뽑을 수 있다. 결과를 텍스트 파일로 다운로드하는 기능도 있어서 SQL INSERT 문에 바로 붙여넣기 좋다.
UUID 포맷 정리
| 포맷 | 예시 | 사용처 |
|---|---|---|
| 기본(하이픈) | 550e8400-e29b-41d4-... | 대부분의 DB, API |
| 하이픈 제거 | 550e8400e29b41d4... | 파일명, 축약 필요 시 |
| 중괄호 | {550e8400-e29b-...} | Windows COM, .NET GUID |
| URN | urn:uuid:550e8400-... | XML, SOAP 메시지 |
UUID는 단순해 보이지만 분산 환경에서 ID 충돌 없이 데이터를 관리하는 핵심 도구다. 순번 ID와 UUID 중 무조건 하나가 낫다는 건 아니고, 서비스 구조에 맞게 선택하면 된다.