UUID vs NanoID와 URL 파라미터 방식 완전 정리

JEONGYUJIN·2025년 6월 1일

목차

  1. UUID와 NanoID 기본 개념
  2. 충돌 확률의 진실
  3. URL 파라미터 방식의 차이
  4. ASP.NET vs 모던 웹의 접근법
  5. 실무 선택 가이드
  6. 개발 시 활용 프롬프트

UUID와 NanoID 기본 개념

웹 개발을 하다 보면 고유한 ID를 생성해야 하는 경우가 정말 많다.
특히 이번 로그인 없이(개인 계정에 저장하는 데이터 없이) 진행하기 때문에 url구조가 복잡하다.

원래 항상 UUID만 생성해서 써왔는데 NanoID라는 걸 알게 되어서 고민이 되길래 찾아보았습니당.

항목UUIDNanoID
길이36자 (하이픈 포함)21~24자 (가변)
예시550e8400-e29b-41d4-a716-446655440000V1StGXR8_Z5jdHi6B-myT
문자 구성하이픈 포함, 영문자 + 숫자URL-safe 문자만 사용
표준화RFC 4122 공식 표준비표준 (라이브러리 기반)
지원 언어/프레임워크거의 모든 언어에서 기본 제공다양한 언어에서 라이브러리 제공, 다소 제한적
DB 지원PostgreSQL, MySQL 등에서 네이티브 지원문자열로 저장, 별도 최적화 없음
전역 고유성전 세계적으로 고유성 보장충분히 고유하지만 충돌 확률 존재
가독성하이픈으로 인해 낮음짧고 깔끔, 하이픈 없음
URL 사용길고 복잡해 부적합URL-safe, 바로 사용 가능
저장 효율성길고 인덱스 크기 큼UUID보다 약 40% 짧아 저장 공간 효율적
레거시 지원뛰어남일부 오래된 시스템에서는 미지원
커스터마이징불가능 (고정 형식)길이, 문자 집합 등 커스터마이징 가능

레거시 호환성, 표준성 중시 → UUID
가볍고 URL에 쓰기 좋은 ID → NanoID


충돌 확률의 진실

"UUID v4와 NanoID의 충돌 확률을 비교하고, 어떤 경우에 충돌 확률이 더 적은지를 정량적으로 판단하기"를 GPT한테 시켜봤습니다.
결론부터 말하자면, NanoID는 기본 설정 기준에서 UUID보다 더 높은 엔트로피(126비트)를 가지므로, 같은 수의 ID를 생성하는 경우 충돌 확률이 더 낮다. 하지만 대량 생성 시에도 충돌을 완전히 피하려면, 엔트로피와 생성량에 따라 수학적으로 충돌 확률을 검토해야한다. 특히 NanoID의 길이나 문자 집합을 줄일 경우 이점이 사라질 수 있다.


⚙️ 1. 기본 전제 조건

항목UUID v4NanoID (기본 설정)
엔트로피122비트약 126비트
가능한 조합 수21225.3×10362^{122} \approx 5.3 \times 10^{36}21268.5×10372^{126} \approx 8.5 \times 10^{37}
생성 개수 nn초당 1조 개 × 100년 = 1012×3.2×109=3.2×102110^{12} \times 3.2 \times 10^9 = 3.2 \times 10^{21}

🧮 2. 충돌 확률 근사 계산 (Birthday Problem)

https://velog.io/@yujin_jeong/Birthday-Problem
참고하시길

충돌 확률은 다음 공식으로 근사됩니다.

P(충돌)n22dP(\text{충돌}) \approx \frac{n^2}{2d}
  • nn: 생성한 총 ID 개수
  • dd: 가능한 고유 조합 수

📊 UUID v4 충돌 확률

n=3.2×1021,d=5.3×1036n = 3.2 \times 10^{21}, \quad d = 5.3 \times 10^{36}
PUUID(3.2×1021)22×5.3×1036=1.024×10431.06×10379.66×105P_{\text{UUID}} \approx \frac{(3.2 \times 10^{21})^2}{2 \times 5.3 \times 10^{36}} = \frac{1.024 \times 10^{43}}{1.06 \times 10^{37}} \approx 9.66 \times 10^5

⚠️ 이 값은 1보다 훨씬 큼 → 즉, 100년 동안 1조 개/초 생성하면 거의 확실히 충돌합니다....하하


📊 NanoID 충돌 확률

n=3.2×1021,d=8.5×1037n = 3.2 \times 10^{21}, \quad d = 8.5 \times 10^{37}
PNanoID(3.2×1021)22×8.5×1037=1.024×10431.7×10386.02×104P_{\text{NanoID}} \approx \frac{(3.2 \times 10^{21})^2}{2 \times 8.5 \times 10^{37}} = \frac{1.024 \times 10^{43}}{1.7 \times 10^{38}} \approx 6.02 \times 10^4

여전히 충돌이 거의 확실하지만, UUID보다 약 16배 낮은 확률입니다.


📉 3. 어느 수준에서 "충돌 확률이 매우 낮다"고 볼 수 있나?

  • 충돌 확률이 <109< 10^{-9}: 실용적으로 안전한 수준
  • 이를 만족하려면,
n22d<109n<2d×109\frac{n^2}{2d} < 10^{-9} \Rightarrow n < \sqrt{2d \times 10^{-9}}

예시로, NanoID의 d = 8.5 × 10³⁷를 넣으면

n<2×8.5×1037×109=1.7×10291.3×1014n < \sqrt{2 \times 8.5 \times 10^{37} \times 10^{-9}} = \sqrt{1.7 \times 10^{29}} \approx 1.3 \times 10^{14}

즉, NanoID로 충돌 확률이 10⁻⁹ 미만이 되려면 총 생성 수가 약 100조 개 이하여야 함


✅ 결론

조건UUID v4NanoID (21자, 64문자)
생성량이 매우 많을 때 (초당 1조 × 수십 년)✅ NanoID가 더 안전 (엔트로피 높음)✅ 충돌 확률은 더 낮지만 여전히 충돌 가능
생성량이 적거나 중간 수준일 때둘 다 안전둘 다 안전
커스터마이징된 NanoID (짧은 길이 등)🚫 충돌 확률 증가 가능🚫 길이가 짧으면 위험 증가
엔트로피 보장된 상태에서 비교할 때UUID: 122비트✅ NanoID: 126비트 → 더 안전

;; 그정도로 충돌하는 케이스면.. 음... 본인 불운이라고 생각하세요;


URL 파라미터 방식의 차이

URL에서 ID를 전달하는 방식은 크게 두 가지가 있다.

구분Path ParameterQuery Parameter
URL 형태/posts/abc123xyz/product?id=abc123
목적리소스 자체를 식별리소스에 대한 옵션/필터
SEO유리 (각각 다른 페이지로 인식)불리 (같은 페이지의 변형으로 인식)
가독성깔끔하고 직관적복잡할 수 있음
파라미터 개수보통 1개여러 개 조합 가능
캐싱쉬움복잡함 (파라미터 조합별)
API 스타일RESTful에서 선호전통적 웹에서 선호

실제 사용 예시

Path Parameter 방식:

✅ https://blog.com/posts/abc123xyz
✅ https://github.com/user/repo/issues/123  
✅ https://youtube.com/watch/dQw4w9WgXcQ

Query Parameter 방식:

✅ https://aladin.co.kr/shop/wproduct.aspx?ItemId=343631553
✅ https://amazon.com/product?asin=B08N5WRWNW
✅ https://google.com/search?q=nanoid&hl=ko&type=web

ASP.NET vs 모던 웹의 접근법

ASP.NET 전통 방식

// ASP.NET Web Forms 스타일
https://site.com/ProductDetail.aspx?ProductId=12345&CategoryId=567

특징:

  • 페이지 기반 라우팅
  • Query String 중심
  • 상태 관리가 복잡
  • 여러 파라미터 조합

💼 왜 이런 방식을 쓰나!
ASP.NET Web Forms는 Windows Forms 개발 경험을 웹으로 가져오려 했다. 그래서 페이지 단위로 생각하고, 파라미터를 통해 상태를 전달하는 방식이 자연스러웠다.

모던 웹 접근법

// React/Vue/Angular 스타일
https://site.com/products/abc123xyz
https://site.com/users/def456uvw/posts/ghi789rst

특징:

  • 컴포넌트 기반
  • Path Parameter 선호
  • 클라이언트 사이드 라우팅
  • RESTful 설계
구분ASP.NET 전통모던 웹
라우팅Query 중심Path 중심
ID 형태숫자 ID 선호UUID/NanoID 선호
URL 예시/page.aspx?id=123/items/abc123
SEO상대적으로 불리유리
가독성복잡함직관적

실무 선택 가이드

UUID를 선택해야 하는 경우

🏦 엔터프라이즈 시스템

  • 금융, 의료, 정부 시스템
  • 절대적 고유성이 생명인 경우
  • 레거시 시스템과 연동 많음

구체적 시나리오:

  • 데이터베이스 Primary Key (특히 분산 환경)
  • 마이크로서비스 간 통신
  • 결제 트랜잭션 ID
  • 의료 기록 식별자

NanoID를 선택해야 하는 경우

🚀 사용자 중심 서비스

  • 공유 기능이 중요한 서비스
  • 모바일 앱, 소셜 서비스
  • URL 길이가 민감한 경우

구체적 시나리오:

  • 단축 URL 서비스 (bit.ly, tinyurl)
  • 게임 방 코드 (ABC123으로 입장하세요!)
  • 초대 링크 (Discord, Slack 등)
  • 파일 공유 링크
  • QR 코드에 들어갈 ID

데이터베이스별 고려사항

데이터베이스UUIDNanoID
PostgreSQLuuid 타입 네이티브varchar(24)
MySQLCHAR(36) 또는 BINARY(16)VARCHAR(24)
MongoDBObjectId 대신 사용 가능더 간결해서 선호
SQLiteTEXTTEXT

개발 시 활용 프롬프트

실제 개발할 때 Cursor나 다른 AI 도구에서 사용할 수 있는 프롬프트를 정리해봤다.

한글 프롬프트 이런거 쓰고 시작하면 편함!

UUID 기반 개발

PostgreSQL과 Node.js Express를 사용해서 게시글 CRUD API를 만들어줘. 
다음 조건을 만족해야 해:

1. 게시글 ID는 UUID v4를 사용
2. 데이터베이스에서 uuid 타입으로 저장
3. RESTful API 설계 (GET /posts/:id 형식)
4. TypeScript 사용
5. 에러 처리 포함

스키마부터 라우터까지 전체 코드를 작성해줘.

🎯 결론

UUID: 엔터프라이즈, 데이터베이스 중심, 절대 안전성
NanoID: 사용자 경험, URL 친화적, 모던 웹

둘 다 충분히 안전하니까, 프로젝트 성격에 맞게 선택하면 된다!

profile
일단 하고 보자 (펠리컨적 마인드 ㅠㅠ)

0개의 댓글