UUID · ULID 생성기
UUID v4·v7, ULID, Nano ID를 원하는 개수만큼 생성합니다. v7과 ULID는 생성 시각을 되꺼낼 수도 있습니다.
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
v7 UUID와 ULID는 앞부분에 타임스탬프가 들어 있어 생성 시각을 되꺼낼 수 있습니다.
네 가지 식별자의 차이
| 형식 | 길이 | 정렬 가능 | 특징 | |---|---|---|---| | UUID v4 | 36자 | 아니오 | 완전 무작위. 가장 널리 쓰임 | | UUID v7 | 36자 | 예 | 앞 48비트가 타임스탬프 | | ULID | 26자 | 예 | 짧고 URL에 그대로 넣기 좋음 | | Nano ID | 21자 | 아니오 | 가장 짧음. URL 친화적 |
도구 사용법
식별자 종류와 생성 개수(1·5·10·50개)를 고르면 바로 만들어집니다. 개별 복사 버튼과 전체 복사 버튼이 있어, 테스트 데이터에 넣을 ID 수십 개를 한 번에 줄바꿈으로 가져갈 수 있습니다. 새로 고침하거나 종류를 바꾸면 새 값이 나오며, 만든 값은 어디에도 저장되지 않습니다.
아래 생성 시각 확인 칸에 UUID v7이나 ULID를 붙여 넣으면 그 안에 든 시각을 읽어 줍니다. 로그에서 발견한 ID가 언제 만들어졌는지 확인하거나, 데이터베이스의 v7 키를 보고 삽입 시점을 추정할 때 씁니다. v4와 Nano ID는 시각 정보가 없어 아무것도 나오지 않습니다.
생김새로 종류 알아보기
이 도구가 만든 값을 예로 들면 다음과 같습니다.
| 종류 | 예시 | 구분법 |
| ------- | -------------------------------------- | ----------------------------- |
| UUID v4 | e0565e28-83a0-4a9a-97af-53d837c562a3 | 세 번째 묶음이 4로 시작 |
| UUID v7 | 01a07644-9040-716c-8f2a-0f586a842500 | 세 번째 묶음이 7로 시작 |
| ULID | 01M1V49420NPCJMR2T2E5X7FHH | 대문자·숫자 26자, 하이픈 없음 |
| Nano ID | cJabPzyHFAXvRIrCziQX8 | 대소문자 섞인 21자 |
UUID는 8-4-4-4-12자로 나뉜 32개의 16진수입니다. 세 번째 묶음의 첫 글자가 버전이고, 네 번째 묶음의 첫 글자는 8·9·a·b 중 하나로 규격 변형을 나타냅니다. 위 v7 예시는 앞 12자리 01a076449040이 밀리초 타임스탬프이고 생성 시각 확인 칸에 넣으면 2026년 9월 6일 10시 30분(UTC)이 나옵니다.
UUID는 대소문자를 구분하지 않습니다. 규격상 소문자로 출력하고 입력은 양쪽 다 받게 되어 있어, 대문자로 저장된 값과 소문자 값은 같은 ID입니다. 다만 문자열로 비교하는 코드에서는 다르게 취급되므로 저장할 때 한쪽으로 통일해야 합니다. ULID는 규격이 대문자입니다.
UUID v4와 v7 중 무엇을 쓸까
데이터베이스 기본키라면 v7입니다.
v4는 완전 무작위라 새 행이 인덱스 여기저기에 흩어져 삽입됩니다. B-트리 인덱스에서 이는 페이지 분할을 계속 일으켜 삽입 성능을 떨어뜨리고 인덱스를 비대하게 만듭니다. 테이블이 커질수록 차이가 벌어집니다.
v7은 앞 48비트가 밀리초 타임스탬프라 생성 순서대로 정렬됩니다. 새 행이 항상 인덱스 끝에 붙어 순차 증가 정수와 비슷한 지역성을 얻습니다.
반대로 생성 시각이 노출되면 곤란한 값이라면 v4를 써야 합니다. v7은 언제 만들어졌는지 누구나 읽을 수 있습니다. 초대 코드나 공개 URL에 들어가는 식별자라면 이 점을 고려하세요.
UUID가 겹칠 가능성
v4는 122비트의 무작위 값을 갖습니다. 경우의 수가 약 5.3 × 10³⁶입니다.
초당 10억 개씩 생성해도 충돌 확률이 50%에 도달하려면 85년이 걸립니다. 실무에서 충돌을 걱정할 필요는 없습니다.
단, 이는 난수원이 충분히 무작위할 때의 이야기입니다. Math.random() 기반으로 UUID를 만드는 구현은 실제로 충돌한 사례가 있습니다. 이 도구는 브라우저의 암호학적 난수 생성기(crypto.getRandomValues)를 씁니다.
Nano ID는 언제 쓰나
Nano ID는 기본 21자로 UUID보다 훨씬 짧으면서 무작위 비트는 126비트로 v4(122비트)와 비슷합니다. 영문 대소문자·숫자·_·-만 쓰므로 URL과 파일명에 그대로 넣을 수 있습니다. 공유 링크의 짧은 코드, 프론트엔드에서 임시로 붙이는 요소 ID, 파일 업로드 이름처럼 데이터베이스 기본키가 아닌 곳에 잘 맞습니다.
길이를 줄이면 그만큼 충돌 가능성이 커집니다. 8자짜리 초대 코드처럼 짧은 값은 사용자가 쉽게 입력할 수 있는 대신 무작위로 맞힐 수도 있으므로, 만료 시간이나 시도 횟수 제한을 함께 두어야 합니다.
ULID의 장점
ULID는 26자 Crockford Base32 문자열입니다.
- 짧습니다. UUID 36자보다 10자 짧고 하이픈이 없어 URL에 그대로 넣기 좋습니다.
- 정렬됩니다. 앞 10자가 타임스탬프라 사전순 정렬이 곧 시간순입니다.
- 헷갈리지 않습니다. Crockford Base32는
I,L,O,U를 제외합니다. 숫자 1과 대문자 I, 숫자 0과 대문자 O를 혼동할 일이 없어 사람이 전화로 불러 주거나 손으로 옮겨 적을 때 유리합니다.
순차 증가 정수(auto increment)를 안 쓰는 이유
정수 기본키는 인덱스 효율이 가장 좋지만 몇 가지 문제가 있습니다.
정보가 새어 나갑니다. /orders/1523이라는 URL은 "지금까지 주문이 1,523건"임을 알려 줍니다. 경쟁사에 사업 규모를 노출하는 셈입니다. 또 번호를 하나씩 바꿔 가며 남의 데이터에 접근을 시도하는 공격의 표적이 됩니다.
분산 환경에서 어렵습니다. 여러 서버나 샤드가 동시에 ID를 만들면 조율이 필요합니다. UUID와 ULID는 서로 통신하지 않고도 겹치지 않는 ID를 만들 수 있습니다.
병합이 어렵습니다. 두 데이터베이스를 합칠 때 정수 키는 반드시 충돌합니다.
사람이 읽는 번호는 따로 둡니다
UUID는 기계가 구분하기 위한 값이지 사람이 부르기 위한 값이 아닙니다. 고객센터에서 "주문번호가 어떻게 되세요"라고 물었을 때 36자를 불러 줄 수는 없습니다. 실무에서는 내부 키는 UUID나 ULID로 두고, 화면과 영수증에는 ORD-20260906-0153 같은 별도의 표시용 번호를 만들어 함께 저장합니다. 표시용 번호는 날짜와 일련번호로 만들어도 됩니다. 노출되어도 내부 키와 연결되지 않으니 위에서 말한 정보 유출 문제가 생기지 않습니다.
UUID의 앞 8자만 잘라 화면에 보여 주는 경우도 있는데, 그 8자는 식별자가 아니라 눈으로 구별하기 위한 힌트일 뿐입니다. 앞 8자가 같은 두 값이 있을 수 있으므로 검색이나 조회 조건에는 전체 값을 써야 합니다.
저장 방식
UUID를 데이터베이스에 넣을 때는 저장 타입이 성능을 좌우합니다.
- PostgreSQL: 전용
uuid타입이 있습니다. 16바이트로 저장됩니다. - MySQL:
BINARY(16)이 권장됩니다.CHAR(36)으로 저장하면 36바이트를 쓰고 인덱스도 두 배 이상 커집니다.
문자열로 저장하는 것은 편하지만 비용이 큽니다. 행이 수천만 개가 되면 차이가 확연히 드러납니다.
함께 확인하면 좋은 것
되돌릴 수 없는 지문이 필요하다면 해시 생성기를, v7이나 ULID에서 꺼낸 시각을 다루려면 타임스탬프 변환기를 이용하세요.