왜 식별자가 중요한가?
식별자(ID)는 데이터를 구분하기 위한 가장 기본적인 정보예요. 사용자 1명, 게시글 1개, 주문 1건이 다른 모든 것과 구별되도록 유일한 값을 부여합니다. 단순해 보이지만 ID 설계가 잘못되면 시스템이 커진 뒤 충돌·재발급·데이터 노출 같은 큰 문제를 만들어요. ID는 한 번 발급되면 거의 영구적으로 따라다니니, 처음 설계할 때 환경에 맞는 형식을 고르는 게 중요합니다. 정수 자동 증가, UUID, 짧은 랜덤 문자열, 타임스탬프 기반 ID 등 선택지가 여럿이고 각각 강점이 달라요.
정수 자동 증가 (auto increment)
가장 단순한 방식은 데이터베이스가 1, 2, 3처럼 자동으로 1씩 증가시키는 정수 ID입니다. 대부분의 RDB(MySQL의 AUTO_INCREMENT, PostgreSQL의 SERIAL/BIGSERIAL)에서 기본 제공해요. 장점은 짧고 사람이 읽기 쉽고, 인덱스가 작아 쿼리 성능이 좋다는 점입니다. 단점도 있어요.
- 순서 노출: /post/1234 같은 URL에서 다음 ID를 추측 가능. 사용자 수·게시글 수가 그대로 노출됨.
- 여러 DB 합치기 어려움: 분산 시스템에서 두 DB의 1번이 충돌. 단일 DB 가정에 묶임.
- 순회 가능: /user/1, /user/2, ... 로 무차별 접근 시도 가능.
내부 시스템·관리자 도구처럼 ID가 노출되지 않는 곳에서는 단순함이 큰 장점이에요. 외부에 노출되는 식별자에는 추천하지 않습니다.
UUID - 충돌 없이 글로벌하게 유니크
UUID(Universally Unique Identifier)는 128비트 길이의 식별자로, 보통 32자 16진수와 4개 하이픈으로 표시돼요(예: 550e8400-e29b-41d4-a716-446655440000). 가장 큰 장점은 여러 시스템·서버에서 동시에 만들어도 거의 충돌이 없다는 점입니다. 가능한 조합이 2의 122제곱이라 사실상 무한해요. 그래서 분산 시스템·마이크로서비스·오프라인 동기화·이벤트 스트림 등에서 표준입니다.
가장 자주 쓰는 버전은 다음 두 가지예요.
- UUID v4: 완전 랜덤. 가장 흔하게 쓰임. 라이브러리 한 줄로 생성.
- UUID v7: 타임스탬프 기반(2022년 표준). 시간 순서로 정렬되어 DB 인덱스 성능이 v4보다 좋음.
단점은 길이가 36자라 URL이 길어지고, v4는 무작위라 DB 인덱스에 친화적이지 않다는 점입니다. v4 ID로 쌓이는 테이블은 인덱스 분산이 심해 성능이 천천히 떨어질 수 있어요. 그래서 최근에는 v7이나 ULID처럼 타임스탬프 기반 ID가 떠오르고 있습니다.
짧은 랜덤 문자열 - URL에 노출되는 ID
YouTube의 비디오 ID(dQw4w9WgXcQ), 트위터의 트윗 ID, GitHub의 짧은 토큰처럼 8~12자 정도의 랜덤 문자열도 자주 쓰여요. UUID보다 짧아 URL이 깔끔하고, 정수 ID처럼 순서를 노출하지 않습니다. 보통 영문 대소문자 + 숫자 62가지(Base62)에서 8자(약 47비트)면 약 218조 개의 조합이 가능해, 작은 서비스에서는 충돌 없이 충분합니다. nanoid 같은 라이브러리가 표준이고, 길이를 자유롭게 조정할 수 있어요. 단점은 충돌 검사를 직접 해야 한다는 점인데, 길이가 충분하면 사실상 일어나지 않습니다.
타임스탬프 기반 ID - ULID, Snowflake
분산 환경에서 UUID v4의 단점을 보완하기 위해 등장한 형식이에요.
- ULID: 128비트, 26자 Base32. 앞 48비트가 타임스탬프(밀리초), 뒤 80비트가 랜덤. 시간순 정렬 가능, 사람이 약간 읽기 좋은 형태.
- Snowflake (Twitter): 64비트 정수. 타임스탬프 + 머신 ID + 시퀀스. 분산 환경에서 ID를 직접 만들 수 있고 정수라 인덱스 효율 좋음.
- UUID v7: 위에서 본 새 버전. ULID와 비슷한 컨셉.
이런 ID는 시간순으로 정렬되니 최신 데이터를 빠르게 조회하기 쉽고, DB 인덱스 성능도 좋아요. 다만 생성 시각이 ID에서 추정 가능하니 보안 민감한 토큰에는 부적합합니다.
어떤 상황에 어떤 ID를 써야 할까?
| 상황 | 추천 식별자 |
|---|---|
| 내부 관리·관리자 페이지 | 정수 자동 증가 |
| 외부 노출 사용자/게시글 ID | UUID v7 또는 ULID |
| 분산 시스템·마이크로서비스 | UUID v4 또는 v7 |
| 짧은 URL이 중요한 서비스 (영상·블로그 슬러그) | nanoid 8~10자 |
| 보안 토큰·세션 ID·비밀번호 재설정 링크 | 충분히 긴(20자 이상) 암호학적 랜덤 |
| 트랜잭션·주문 ID | UUID v7 또는 Snowflake |
가장 흔한 실패는 모든 곳에 정수 ID를 쓰는 것과 모든 곳에 UUID를 쓰는 것 두 가지예요. 환경에 맞는 식별자를 골라 쓰는 게 좋습니다.
도구로 식별자 만들기
툴박스의 UUID 생성기는 UUID v4와 짧은 랜덤 문자열을 즉시 생성합니다. 개발 중 mock 데이터를 만들거나, 새 사용자 ID·세션 토큰을 시도해볼 때 빠르게 사용할 수 있어요. 다만 실제 프로덕션 코드에서는 라이브러리를 사용하고, 보안에 민감한 토큰은 암호학적으로 안전한 난수 생성기(crypto.randomUUID, secrets.token_urlsafe)를 쓰는 것이 안전합니다.


