스노우플레이크 방식으로 주문번호 생성하기

2025. 3. 10. 09:44·TIL (Today I Learned)

개요

Orders 테이블에 order_id 컬럼을 order_no 컬럼으로 변경하면서,

PK 생성 방식을 AUTO_INCREMENT에서 다른 방식으로 변경이 필요했다.

 

스노우플레이크 알고리즘을 선택한 이유

  1. 분산 환경에서 장점이 있는 알고리즘
        스노우플레이크 알고리즘은 분산 환경에서 고유한 ID를 생성하는 데 최적화된 알고리즘이다.
        우리 프로그램은 단일 서버에서 단일 스레드로 동작하는 구조라 분산 시스템은 아니지만,
        적용해보며 학습하고 싶었다.
  2. 가독성 문제
        주문 목록 조회 API에서 주문번호를 유저가 직접 확인할 수 있도록 설계했다.
        하지만 UUID(128비트)는 문자열 길이가 길어 가독성이 떨어지는 문제가 있어, 더 짧고 직관적인 ID가 필요했다.
  3. DB에서 유리
        UUID보다 짧은 길이를 가지므로 DB 저장 및 검색 성능에 유리하다.
        데이터베이스 인덱싱 효율이 높아지고, bigint(64비트) 타입으로 저장할 수 있어 관리가 용이하다.

참고: https://f-lab.kr/insight/uuid-vs-snowflake-20241230

 

효율적인 주문 번호 생성: UUID와 스노우플레이크 알고리즘 비교

UUID와 스노우플레이크 알고리즘을 비교하여 효율적인 주문 번호 생성 방법을 탐구합니다. 각각의 장단점과 적용 사례를 통해 적합한 선택 기준을 제시합니다.

f-lab.kr

 

적용 방법

public class SnowflakeOrderNoGenerator {
    private static final long epoch = 1740787200000L;  // 2025-03-01 00:00:00 UTC
    private static final long machineId = 0L;  // 단일 서버
    private static final long maxSequence = 4095;  // 같은 밀리초에서 4096개 ID 생성 가능

    private static long lastTimestamp = -1L;   // 마지막으로 생성한 타임 스탬프
    private static long sequence = 0L; // 같은 밀리초에서 증가하는 시퀀스 값

    public static synchronized long generateOrderNo() {
        long currentTimestamp = System.currentTimeMillis();

        if (currentTimestamp < lastTimestamp) {
            throw new IllegalStateException("Clock moved backwards. Refusing to generate ID");
        }

        // 같은 밀리초인 경우 sequence 값 증가
        if (currentTimestamp == lastTimestamp) {
            sequence = (sequence + 1) & maxSequence;
            if (sequence == 0) {
                while (currentTimestamp <= lastTimestamp) {
                    currentTimestamp = System.currentTimeMillis();
                }
            }
        } else {
            sequence = 0;
        }

        lastTimestamp = currentTimestamp;

        // 순차적이고 유일한 64비트 정수형 ID 생성
        return ((currentTimestamp - epoch) << 22) | (machineId << 12) | sequence;
    }
}
  • 유일성 보장: ID를 69년(41비트) 동안 안전하게 사용할 수 있음
  • 생성된 주문번호 예시: 917997178847232

참고: https://www.catsriding.com/posts/implementing-unique-id-generator-based-on-snowflake-algorithm-in-java

 

catsriding | 다양한 유일 ID 생성 전략 비교 및 Snowflake 기반 기본키 도입하기

유일 ID 생성은 데이터 무결성뿐만 아니라 분산 환경에서의 안정성 확보와 대규모 배치 작업에서의 효율성을 위해 필수적입니다. 자동 증가 키 전략은 충돌 위험이 있고, UUID 방식의 기본키는 길

www.catsriding.com

 

저작자표시 비영리 변경금지 (새창열림)

'TIL (Today I Learned)' 카테고리의 다른 글

H2 콘솔 접속 시 Whitelabel Error Page (400 Bad Request) 해결 과정 + spring boot에서 active profile 선택하기 (IntelliJ)  (0) 2025.03.12
H2 데이터베이스 설치 방법 | Server / In-memory / Embedded Mode❔  (0) 2025.03.10
SPRING ADVANCED 과제 | ‘내’가 정의한 문제와 해결 과정 기록 📜  (0) 2025.02.27
Spring Security를 활용한 JWT 인증 적용해보기 🖥️🔑  (0) 2025.02.27
Interceptor와 AOP 개념 정리 및 API 로깅 예시 ✍️  (0) 2025.02.26
'TIL (Today I Learned)' 카테고리의 다른 글
  • H2 콘솔 접속 시 Whitelabel Error Page (400 Bad Request) 해결 과정 + spring boot에서 active profile 선택하기 (IntelliJ)
  • H2 데이터베이스 설치 방법 | Server / In-memory / Embedded Mode❔
  • SPRING ADVANCED 과제 | ‘내’가 정의한 문제와 해결 과정 기록 📜
  • Spring Security를 활용한 JWT 인증 적용해보기 🖥️🔑
기만나🐸
기만나🐸
공부한 내용을 기록합시다 🔥🔥🔥
  • 기만나🐸
    기만나의 공부 기록 🤓
    기만나🐸
  • 전체
    오늘
    어제
    • ALL (147)
      • TIL (Today I Learned) (56)
      • Dev Projects (15)
      • Algorithm Solving (67)
        • Java (52)
        • SQL (15)
      • Certifications (8)
        • 정보처리기사 실기 (8)
  • 인기 글

  • 태그

    완전탐색
    자료구조
    bootstrap
    javascript
    그리디
    BFS
    programmers
    DFS
    HTML
    CSS
    Google Fonts
    백트래킹
    websocket
    프로그래머스
    java
    백준
    jwt
    Subquery
    dp
    jpa
    jQuery
    BOJ
    sql
    join
    다이나믹프로그래밍
    greedy
    mysql
    GROUP BY
    Firebase
    시뮬레이션
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
기만나🐸
스노우플레이크 방식으로 주문번호 생성하기
상단으로

티스토리툴바