본문 바로가기

[DB] UUID를 사용한 고유한 ID 시스템의 장점과 적용 방법

@Jeeqong 2025. 3. 23. 15:15
반응형

1. UUID(Universally Unique Identifier)를 orders 테이블의 order_id로 설정한 이유

1.1 전역적으로 고유한 ID 보장

  • order_id를 UUID로 설정하면 ID 충돌 가능성이 거의 없음.
  • AUTO_INCREMENT(자동 증가 ID) 방식은 같은 데이터베이스 내에서만 유일하지만, UUID는 여러 서버, 여러 데이터베이스에서도 고유성을 보장.
  • 만약 마이크로서비스 아키텍처를 사용한다면, 데이터베이스가 분리되더라도 UUID가 충돌할 일이 없음.

1.2 수동 ID 관리 없이 독립적 데이터 생성 가능

  • 일반적인 INT AUTO_INCREMENT 방식에서는 데이터베이스에서 ID를 생성해야 함.
  • UUID는 애플리케이션 레벨에서 미리 생성 가능하기 때문에, 데이터베이스에 미리 삽입하지 않아도 ID를 만들 수 있음.
  • 특히 분산 시스템에서 데이터를 미리 준비할 때 유용함.

📌 예제: Python에서 UUID 생성

import uuid

new_id = str(uuid.uuid4())  # 랜덤 UUID 생성
print(new_id)  
# 👉  "b4dbac9e-6a1c-467b-bf62-d89f3f3e3497"

이렇게 Python에서 UUID를 미리 생성해서, 데이터베이스에 삽입할 때 바로 사용 가능.


1.3 보안성 강화 (ID 추측 방지)

  • AUTO_INCREMENT (1, 2, 3, ...) 방식은 순차적인 증가 값이므로, 다음 ID를 쉽게 추측 가능. → 악의적인 유저가 URL을 조작해서 다른 데이터에 접근할 가능성이 있음.
  • UUID는 랜덤하게 생성되므로, ID를 추측할 수 없음.

📌 예제: ID를 사용한 URL 보안 차이

🔴 취약한 예시 (AUTO_INCREMENT)
https://example.com/orders/1
https://example.com/orders/2  🚨 ID 변경하면 다른 주문 데이터 접근 가능

🟢 안전한 예시 (UUID)
https://example.com/orders/b4dbac9e-6a1c-467b-bf62-d89f3f3e3497
https://example.com/orders/9f3e449a-2a6c-44b2-b84f-89ea83e7e6a8
  • UUID는 예측할 수 없기 때문에, 직접 접근이 어려움.
  • 특히 **API에서 리소스 보호(Security by obscurity)**를 강화할 때 유용.

1.4 분산 시스템 & 데이터 동기화에 유리

  • UUID는 여러 데이터베이스에서 동시에 생성 가능하므로,
    **분산 시스템(Distributed Systems)**에서 충돌 없이 데이터 동기화 가능.
  • AUTO_INCREMENT는 단일 데이터베이스 환경에서만 유효하지만,
    UUID는 여러 데이터베이스에서 생성해도 중복될 가능성이 극히 낮음.

📌 예제: 여러 서버에서 독립적으로 UUID 생성

  • 여러 개의 **서버(마이크로서비스 구조)**에서 데이터를 생성하는 경우:
    • 각 서버가 독립적으로 UUID를 생성할 수 있음.
    • 동기화할 필요 없이, 각 서버가 데이터를 병합할 수 있음.

1.5 ID를 변경해도 DB 성능 유지 (Shard Key로 활용)

  • UUID는 특정 패턴을 가지므로, 데이터베이스 샤딩(Sharding)에 유리.
  • 예를 들어, MySQL, PostgreSQL 같은 DB에서 UUID를 활용한 파티셔닝(Partitioning)이 가능.
  • 대규모 데이터를 다룰 때, 특정 ID 범위별로 샤딩(Sharding)할 수도 있음.

2. 하지만 UUID의 단점은?

2.1 길이가 길다 (vs. INT)

  • INT(4 bytes) vs. UUID(16 bytes)
  • 저장 공간이 더 많이 필요하고, 인덱싱 속도가 느릴 수 있음.

2.2 가독성이 떨어짐

  • 12345 같은 숫자보다 b4dbac9e-6a1c-467b-bf62-d89f3f3e3497는 읽기가 어려움.

2.3 데이터베이스 인덱스 크기 증가

  • UUID가 길기 때문에, 인덱스 크기가 커지고 검색 속도가 조금 느려질 수 있음.

3. UUID 단점 해결 방법

3.1 UUID를 BINARY(16)로 저장 (MySQL, PostgreSQL)

  • UUID 문자열(VARCHAR(36))을 그대로 저장하면 비효율적.
  • 대신 BINARY(16) 형태로 변환하면 저장 공간을 절약할 수 있음.

📌 MySQL 예제

ALTER TABLE orders ADD COLUMN order_id BINARY(16) PRIMARY KEY;

3.2 UUIDv4 대신 UUIDv1 사용

  • UUIDv4는 완전 랜덤이지만, UUIDv1은 시간 기반이므로 정렬이 용이.
  • UUIDv1을 사용하면 인덱스 정렬이 최적화됨.

📌 Python에서 UUIDv1 생성

import uuid
print(uuid.uuid1())  # 👉 정렬 가능성이 높은 UUID 생성

4. 결론: 언제 UUID를 사용할까?

상황 AUTO_INCREMENT (INT) UUID(VARCHAR/BINARY(16))
단순한 DB 테이블 (작은 규모 서비스) ✅ 추천 ❌ 불필요
분산 시스템 (여러 DB & 서버 동시 사용) ❌ 충돌 위험 ✅ 강력 추천
보안이 중요한 데이터 (URL로 접근 방지) ❌ ID 추측 가능 ✅ 추천
샤딩(Sharding) 또는 파티셔닝 적용 ❌ ID 패턴으로 불가능 ✅ 추천

5. UUID를 사용하는 이유

  • 분산 환경에서도 고유한 ID 생성
  • 보안 강화 (ID 추측 방지)
  • 데이터 충돌 없이 여러 서버에서 생성 가능
  • 샤딩 및 데이터 동기화에 유리

🔥 마무리

이번 포스트에서는 AUTO_INCREMENT와 UUID를 비교하면서 어떤 환경에서 UUID를 사용하는 것이 좋은지 알아봤어.
💡 특히 마이크로서비스, 보안이 중요한 데이터, 분산 시스템에서는 UUID 사용을 강력 추천!

반응형
Jeeqong
@Jeeqong :: JQVAULT

Jeeqong's vault : 정보/기록을 쌓아두는 공간 웹개발 포스팅 일상 리뷰를 기록하는 공간입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차