업무 중에 “사용자에게 노출되는 주문번호는 어떤 규칙으로 만드는 게 좋을까?”라는 질문을 받았다. 처음엔 그냥 유니크하기만 하면 되는 거 아닌가 싶었는데, 막상 찾아보니 그렇게 단순한 문제가 아니었다.ㅜ.ㅜ)
주문번호는 고객이 주문 조회나 고객센터 문의 때 직접 사용하는 값이다. 동시에 결제, 배송, 환불, 정산 같은 내부 업무와도 연결된다.
그래서 중복이 없어야 하는 건 기본이고, 주문량 같은 운영 정보가 드러나지 않아야 하며, 고객과 상담원이 읽고 전달하기에도 불편하지 않아야 한다.
이번 글에서는 업무 중에 찾아보고 정리한 사용자 노출용 주문번호 생성 기준과 여러 생성 방식의 장단점을 정리해보려고 한다.
🐻❄️ 사용자에게 노출되는 주문번호 규칙
단순히 유니크하기만 하면 되는게 아니라 운영 정보 노출을 막고, CS 조회가 쉬워야 하며, 동시성/성능까지 고려해야 한다.
✏️ 주문번호의 기본 역할
- 사용자가 쇼핑몰에서 구매한 뒤 받는 번호
- 주문 조회나 고객센터 문의 시 쇼핑몰에 제공하는 식별자
- 주문 경로도 웹사이트, 콜센터 같은 여러 경로가 있을 수 있다.
✏️ 주문번호 규칙
☑️ 유일성
같은 주문번호가 두 개 있으면 CS, 결제, 배송, 환불, 정산이 다 꼬이니까 주문번호는 반드시 중복되지 않아야한다.
☑️ 보안성
주문번호가 회사의 실제 운영 정보를 드러내면 안 된다.
예를 들어, 주문번호가 그냥 순차 번호라면 외부인이 주문번호를 보고 전체 주문량이나 운영 규모를 추측할 수 있다. 그래서 주문번호는 회사 내부의 일부 사람 외에는 규칙을 쉽게 알아보기 어렵게 설계하는게 좋다.
☑️ 짧은 랜덤코드만으로 유일성을 보장하려 하면 안 된다.
- 랜덤 코드는 운영 정보 노출을 막는 데는 좋지만, 유일성을 보장하려면 생성할 때마다 과거 데이터와 중복 여부를 확인해야하고, 주문량이 커질 수록 그 부담이 커진다.
- 날짜 prefix를 넣으면 충돌 범위가 전체 주문 누적량이 아니라 하루 주문량 기준으로 줄어드는 장점이 있다. 이게 날짜 + 랜덤 방식이 실무에서 무난한 이유이다.
☑️ 동시성 방지
주문번호에 시간값이 들어갈 때 여러 주문이 동시에 생성되면 중복이 날 수 있으니 시간 기반 생성 규칙을 쓸 때는 동시성 처리가 필요하다.
☑️ 길이 제한
주문번호는 결국 고객이 고객센터에 불러주고, 상담원이 조회하기 위한 값이기도 하니 너무 길면 안좋다.
🔗 참고 : https://www.zhihu.com/en/answer/37150071
🐻❄️ 사용자에게 노출되는 주문번호 생성 방식
✏️ 날짜 + 순번 방식
✏️ 날짜 + 랜덤 문자열 방식
✏️ 고객 ID + 고객의 주문 순번 + orders 테이블의 unique ID 조합
✏️ UUID 또는 ULID 방식
- 예시 :
018F8ZK7M9VQ2B4T6Y8N1C3P5D
- 장점 : 충돌 가능성이 낮음
- 단점 : 사용자에게 직접 노출하기에는 길고, 전화 문의/수기 입력 시 불편할 수 있다.
✏️ timestamp + random code + check digit 구조
✏️ 업무번호 + 연월일 + 당일 주문 수 조합
🐻❄️ 기타
✏️ 랜덤코드를 붙이는 경우
📌 6자리 조합
- 조합 수 : 32^6 = 약 10.7억 개
- 같은 날짜에 주문이 1만건이 들어온다고 했을 때, 하루 충돌 확률 약 4~5% 정도
📌 8자리 조합
- 조합 수 : 32^8 = 약 1.09조 개
- 같은 날짜에 주문이 1만건이 들어온다고 했을 때, 하루 충돌 확률 약 0.005% 정도
☑️ 주문량이 적고 짧은 번호를 선호하는 경우 6자리도 가능하지만, 하루 주문량이 늘거나 프로모션/대량주문 가능성이 있으면 8자리가 더 안정적이다.
✏️ 랜덤 코드 만들 때 제외 고려 해야하는 문자 (수기입력 많을때)
☑️ 전화로 들을 때나 폰트에 따라 헷갈리는 경우는 아래와 같음
0 / O / Q
1 / I / L / l
2 / Z
5 / S
8 / B
6 G
9 g q
C G
U V
M N
☑️ CS 거의 없고 복사 위주라면 : 23456789ABCDEFGHJKLMNPQRSTUVWXYZ 로 구성
- 문자 수 : 32개
- 6자리
1. 랜덤코드 조합 수 : 1,073,741,824 개 (약 10억개)
2. 같은 날짜에 랜덤코드 1만 개를 생성했을 때, 최소 1번 이상 충돌할 확률 : 약 4.55%
- 8자리
1. 랜덤코드 조합 수 : 1,099,511,627,776 (약 1조개)
2. 같은 날짜에 랜덤코드 1만 개를 생성했을 때, 최소 1번 이상 충돌할 확률 : 약 0.00455%
☑️ 전화 문의나 수기 입력도 고려 : 34679ACDEFGHJKMNPRTUVWXY 로 구성
- 문자 수 : 24개
- 6자리
1. 랜덤코드 조합 수 : 191,102,976 개 (약 1억개)
2. 같은 날짜에 랜덤코드 1만 개를 생성했을 때, 최소 1번 이상 충돌할 확률 : 약 23.02%
- 8자리
1. 랜덤코드 조합 수 : 110,075,314,176 개 (약 1000억개)
2. 같은 날짜에 랜덤코드 1만 개를 생성했을 때, 최소 1번 이상 충돌할 확률 : 약 0.0454%
☑️ 아주 보수적으로 : 34679ACDEFHJKMNPRTUVWXY 로 구성
- 문자 수 : 23개
- 6자리
1. 랜덤코드 조합 수 : 148,035,889 개 (약 1억개)
2. 같은 날짜에 랜덤코드 1만 개를 생성했을 때, 최소 1번 이상 충돌할 확률 : 약 28.66%
- 8자리
1. 랜덤코드 조합 수 : 78,310,985,281 개 (약 783억 개)
2. 같은 날짜에 랜덤코드 1만 개를 생성했을 때, 최소 1번 이상 충돌할 확률 : 약 0.0638%