테이블 기본키(Primary Key) 선택 전략: Natural Key vs Surrogate Key

데이터베이스 설계에서 기본키 선택은 성능과 데이터 무결성에 큰 영향을 미치는 중요한 결정입니다. 크게 두 가지 접근 방식이 있는데, 바로 자연키(Natural Key)와 대리키(Surrogate Key)입니다.

자연키(Natural Key)

자연키는 데이터 자체에 존재하는 속성을 기본키로 사용하는 방식입니다.

특징:

  • 비즈니스 데이터에서 자연적으로 발생하는 고유한 값 사용
  • 예: 주민등록번호, 이메일 주소, ISBN 등
  • 추가 컬럼이 필요하지 않아 저장 공간 절약 가능

장점:

  • 자연적인 의미를 가져 직관적인 이해 가능
  • 별도의 키 생성 로직이 필요 없음
  • 데이터 중복 방지에 도움

단점:

  • 변경 가능성 있음 (이메일 주소나 전화번호 등이 변경될 수 있음)
  • 복합키가 필요한 경우 쿼리 복잡성 증가
  • 외래키 참조 시 오버헤드 발생 가능
  • 비즈니스 규칙 변경에 취약

대리키(Surrogate Key)

대리키는 실제 데이터와는 관련 없는 인공적으로 생성된 값을 기본키로 사용하는 방식입니다.

특징:

  • 자동 증가 정수(Auto-increment), UUID, 시퀀스 등 사용
  • 데이터의 실제 속성과는 무관한 값
  • 시스템에 의해 자동 생성 및 관리

장점:

  • 변경되지 않음 (불변성)
  • 단순하고 일관된 키 구조
  • 인덱싱 및 조인 성능이 우수 (특히 정수형)
  • 비즈니스 규칙 변경에 영향받지 않음

단점:

  • 의미 없는 값으로 직관성 떨어짐
  • 추가 저장 공간 필요
  • UUID 사용 시 인덱스 크기 증가로 성능 저하 가능성

정수형 vs UUID 기반 대리키

대리키를 사용할 때 자주 고려되는 두 가지 옵션에 대해 자세히 살펴보겠습니다.

정수형 기본키 (Auto-increment)

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

장점:

  • 저장 공간 효율적 (일반적으로 4바이트)
  • 인덱스 성능 최적화
  • 순차적 삽입으로 인한 페이지 분할 최소화
  • 직관적인 디버깅 및 관리

단점:

  • 분산 시스템에서 생성 복잡
  • 값으로부터 정보 유추 가능 (보안 이슈)
  • 시퀀스 고갈 가능성 (특히 INT 타입 사용 시)

UUID 기반 기본키

CREATE TABLE products (
    id CHAR(36) PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    price DECIMAL(10, 2) NOT NULL
);
// Java에서 UUID 생성 예시
String productId = UUID.randomUUID().toString();

장점:

  • 분산 시스템에 적합 (충돌 가능성 극히 낮음)
  • 데이터베이스 간 마이그레이션 용이
  • 보안 강화 (순차적 예측 불가)
  • ID 생성을 애플리케이션에서 처리 가능

단점:

  • 저장 공간 비효율적 (16바이트 또는 문자열 36바이트)
  • 인덱스 성능 저하
  • 인간 가독성 낮음
  • 랜덤 삽입으로 인한 페이지 분할 가능성 증가

기본키 선택 가이드라인

  1. 시스템 규모와 분산 여부 고려

    • 단일 데이터베이스: Auto-increment 정수형이 성능상 유리
    • 분산 시스템: UUID나 Snowflake ID 같은 대안 고려
  2. 데이터 변경 가능성 분석

    • 변경 가능성이 있는 비즈니스 속성은 자연키로 부적합
    • 불변성이 보장되어야 기본키로 적합
  3. 성능 요구사항 평가

    • 고성능이 필요한 대용량 시스템: 정수형 대리키 선호
    • 조인 작업이 많은 경우: 작은 크기의 키가 유리
  4. 비즈니스 요구사항 고려

    • 외부 시스템과의 통합 필요성
    • 보안 및 개인정보 보호 요구사항