13P by neo 1일전 | ★ favorite | 댓글 3개
  • PostgreSQL 18에서는 UUIDv7을 기본 지원하며, 정렬 가능하고 인덱스 친화적인 고유 식별자를 제공
  • UUIDv7은 기존 UUID의 분산 환경에서의 고유성과 보안성은 유지하면서, btree 인덱스에 유리한 시간 기반 정렬 구조를 채택함
  • 기존 UUID 사용의 단점이었던 정렬 불가, 인덱스 난삽, 메모리 크기 중 앞의 두 문제를 해결하며 시간순 정렬 및 삽입 최적화를 실현함
  • PostgreSQL 18에서는 uuidv7() 함수로 UUID 생성이 가능하고, 타임스탬프 추출 및 커스텀 시간 입력 기능도 제공함
  • 이제 UUID를 기본 키로 사용하는 것을 주저하던 이유가 해소되어, 분산 시스템 및 다중 테넌트 환경에서 더 적합한 선택지가 됨

PostgreSQL 18

  • PostgreSQL 18의 베타 버전이 출시되었고, 9월 정식 릴리스를 목표로 테스트가 진행 중임
  • 주요 기능:
    • Async I/O: io_uring 기반 비동기 입출력으로 시퀀스 스캔 및 vacuum 2~3배 속도 개선
    • 멀티 컬럼 btree 인덱스의 Skip scan, OR/IN 쿼리 최적화
    • 업그레이드 간 플래너 통계 유지
    • UUIDv7 함수
    • 가상 생성 칼럼, OAuth 로그인, EXPLAIN에 I/O/CPU/WAL 정보 추가 등

UUID의 장점

  • 분산 환경에서 고유 ID 생성 가능
  • 예측 불가능한 공개 식별자로 보안성 강화
  • 클라이언트에서 직접 ID 생성 가능하여 서버 통신 최소화

기존 UUID의 단점

  • 정렬 불가능
  • 인덱스 비국소성으로 인한 삽입 성능 저하
  • 128비트 크기로 인한 오버헤드

UUIDv7의 해결책

  • RFC 9562 (2024년 5월 발표) 에 따라 도입된 신형 UUID 버전
  • 앞의 48비트에 Unix Epoch 기반 타임스탬프, 나머지에는 무작위값 + 카운터를 조합
  • 시간 순 정렬 가능하며, 인덱스 삽입 효율 증가
  • UUIDv6는 하위 호환용, UUIDv8은 실험/벤더 확장용
  • UUIDv7만이 실질적으로 의미 있는 새로운 표준

PostgreSQL 18에서의 UUIDv7 사용

  • uuidv7() 함수로 현재 시각 기반 UUID 생성
  • uuidv7(INTERVAL)을 통해 원하는 시간 offset 반영 가능
  • uuid_extract_version(), uuid_extract_timestamp() 함수로 UUID 버전 및 생성 시간 추출 가능
  • 예시:
    CREATE TABLE test (  
        id uuid DEFAULT uuidv7() PRIMARY KEY,  
        name text  
    );  
    
    INSERT INTO test (name) VALUES ('foo');  
    INSERT INTO test (name) VALUES ('bar');  
    INSERT INTO test (id, name) VALUES (uuidv7(INTERVAL '-1 hour'), 'oldest');  
    
    SELECT uuid_extract_timestamp(id), name FROM test ORDER BY id;  
    
  • uuidv4()gen_random_uuid()의 별칭으로 추가됨

결론 및 권장 사항

  • UUIDv7은 기존 UUID 사용 시 성능 문제를 겪던 사용자들에게 적합
  • 정렬성과 인덱스 성능을 확보하면서도 UUID의 장점 유지
  • PostgreSQL 18 베타에서 지금 바로 테스트 가능
  • 분산 시스템, 다중 테넌트 앱, 서버리스 환경에서의 ID 생성에 적합한 선택지

“UUIDv7는 조용하지만 강력한 기능 추가로, Postgres에서 UUID를 기본 키로 사용하는 것을 다시 고려하게 만듦”

uuid_generate_v7() 같은 함수 만들어서 사용하고 있었는데 반가운 소식이네요.