프로그래밍/서버, DBMS

PostgreSQL uuidv7 기준

포도알77 2026. 9. 15. 22:08

본문 중간의 쿠팡 추천 상품 구매시 쿠팡 파트너스에서 일정액의 수수료를 제공받습니다.

PostgreSQL 18 기준으로 uuidv7() 함수가 기본 UUID 생성 함수 목록에 들어왔습니다. UUIDv7은 시간순으로 정렬되기 쉬운 UUID 형식이고, PostgreSQL 문서는 UUIDv4와 UUIDv7 생성을 native로 지원한다고 설명합니다.

선택 기준은 단순합니다. 외부에 노출해도 되는 식별자가 필요하고, 생성 순서가 인덱스와 조회 패턴에서 의미가 있다면 uuidv7()을 검토할 만합니다. 반대로 생성 시각을 식별자에서 추출할 수 있다는 성격이 부담이거나, 이미 애플리케이션 쪽 UUID 정책이 정해져 있다면 무조건 바꿀 이유는 없습니다.

PostgreSQL uuidv7()은 무엇을 만들까?

uuidv7()은 version 7 UUID를 생성하는 PostgreSQL 함수입니다. PostgreSQL 문서 기준으로 UUIDv7의 timestamp는 Unix timestamp의 millisecond precision, sub-millisecond timestamp, random 값을 조합해 계산됩니다.

UUID 컬럼 자체는 특정 버전만 저장하는 타입이 아닙니다. PostgreSQL의 uuid 타입은 UUID 값을 저장하는 데이터 타입이고, 값이 데이터베이스 안에서 생성됐는지 애플리케이션에서 생성됐는지와 무관하게 UUID 값을 저장할 수 있습니다. 차이는 생성 함수와 운영 정책에서 생깁니다.

CREATE TABLE events (
  id uuid PRIMARY KEY DEFAULT uuidv7(),
  event_type text NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now()
);

이 예시는 새 행을 넣을 때 PostgreSQL이 id 값을 직접 만듭니다. 여러 애플리케이션 서버가 같은 테이블에 쓰더라도 UUID 생성 규칙을 데이터베이스 기본값으로 모을 수 있다는 장점이 있습니다.

UUIDv4와 무엇이 다른가?

gen_random_uuid()와 uuidv4()는 version 4 UUID를 생성합니다. UUIDv4는 무작위 기반 UUID입니다. 생성 시각과 정렬 순서 사이에 특별한 관계를 기대하지 않는 식별자에는 여전히 자연스러운 선택입니다.

uuidv7()은 시간순 성격이 있는 UUID를 만듭니다. PostgreSQL 18 릴리스 노트도 uuidv7()을 timestamp-ordered UUID 생성 함수라고 설명합니다. 이 성격 때문에 새로 생성된 값들이 B-tree 인덱스에서 완전히 무작위로 흩어지는 패턴보다 가까운 구간에 놓이기 쉽습니다.

항목 UUIDv4 UUIDv7
PostgreSQL 함수 gen_random_uuid(), uuidv4() uuidv7()
기본 성격 무작위 기반 시간순 정렬에 유리한 형식
적합한 상황 시간 정보가 식별자에 섞이지 않기를 원할 때 최근 생성 데이터가 많고 정렬·인덱스 locality가 중요할 때
주의점 생성 순서와 정렬 순서가 맞지 않는다. 식별자에서 timestamp 추출이 가능할 수 있다.

uuid_extract_timestamp()는 어떻게 봐야 하나?

PostgreSQL은 UUID에서 정보를 꺼내는 함수도 제공합니다. uuid_extract_version(uuid)은 RFC 9562 variant UUID의 version을 반환하고, uuid_extract_timestamp(uuid)는 version 1 또는 version 7 UUID에서 timestamp를 반환합니다. 다른 version에서는 timestamp 추출 결과가 null일 수 있습니다.

SELECT
  uuid_extract_version(id) AS uuid_version,
  uuid_extract_timestamp(id) AS embedded_time
FROM events
ORDER BY id
LIMIT 5;

이 기능은 점검과 디버깅에는 유용합니다. 다만 문서도 추출된 timestamp가 UUID 생성 시각과 반드시 정확히 같지는 않다고 설명합니다. 실제 생성 시각, 접수 시각, 비즈니스 이벤트 시각이 중요하다면 별도의 timestamptz 컬럼을 두는 편이 안전합니다.

 

 

shift 인자는 언제 쓸까?

uuidv7()은 선택적으로 interval 타입의 shift 인자를 받을 수 있습니다. PostgreSQL 문서 기준으로 이 인자는 계산된 timestamp를 지정한 interval만큼 이동합니다. 무한 interval은 받을 수 없고, 이동된 timestamp는 UUIDv7의 48-bit millisecond timestamp 필드가 표현할 수 있는 범위 안에 있어야 합니다.

SELECT uuidv7();
SELECT uuidv7(INTERVAL '1 hour');

일반적인 테이블 기본값에는 인자 없는 uuidv7()이 더 명확합니다. shift는 테스트 데이터나 특정 시점 주변의 UUID를 의도적으로 만들어야 하는 경우처럼 목적이 분명할 때만 쓰는 편이 낫습니다. 운영 데이터의 실제 생성 순서를 일부러 흐리면 정렬과 해석 기준이 어려워질 수 있습니다.

DB에서 만들까, 애플리케이션에서 만들까?

UUID는 데이터베이스에서도 만들 수 있고 애플리케이션에서도 만들 수 있습니다. PostgreSQL 문서는 uuid 타입이 어떤 출처나 버전의 UUID도 저장할 수 있다고 설명합니다. 따라서 핵심은 타입이 아니라 생성 책임을 어디에 둘지입니다.

상황 우선 검토 이유
대부분의 쓰기가 PostgreSQL INSERT를 통해 들어온다. DEFAULT uuidv7() 생성 규칙을 스키마에 고정할 수 있다.
DB에 넣기 전에 ID가 필요하다. 애플리케이션 생성 파일명, 메시지 키, 외부 API 요청 ID에 먼저 쓸 수 있다.
여러 DB와 서비스가 같은 ID 정책을 공유한다. 공통 라이브러리 또는 서비스 각 저장소의 함수 차이를 줄일 수 있다.
식별자에서 생성 시각이 유추되면 곤란하다. UUIDv4 또는 별도 정책 UUIDv7의 시간순 성격이 요구사항과 충돌할 수 있다.

실무 적용 기준

첫째, UUIDv7을 쓰더라도 기본키와 유일 제약은 그대로 필요합니다. UUID 알고리즘이 충돌 가능성을 낮추는 것과 데이터베이스가 중복을 막는 것은 다른 문제입니다. 식별자 컬럼에는 PRIMARY KEY나 UNIQUE 제약을 명확히 둬야 합니다.

둘째, 정렬 기준을 식별자에만 맡기지 않습니다. UUIDv7은 시간순 정렬에 유리하지만, 업무상 정확한 생성 시각이나 이벤트 시각이 필요하다면 별도 timestamp 컬럼을 두고 그 컬럼으로 조회 조건을 작성하는 편이 명확합니다.

셋째, major version을 확인해야 합니다. PostgreSQL 18 문서에는 uuidv7()이 있지만, 오래된 PostgreSQL 버전에서는 같은 함수가 없을 수 있습니다. 마이그레이션 대상이 여러 버전이라면 함수 존재 여부와 애플리케이션 fallback을 같이 설계해야 합니다.

FAQ

PostgreSQL uuidv7()은 어느 버전 기준인가?

PostgreSQL 18 공식 문서 기준입니다. PostgreSQL 18 릴리스 노트에는 uuidv7()이 timestamp-ordered UUID를 생성하는 함수로 추가됐다고 설명되어 있습니다.

uuidv7()을 쓰면 created_at 컬럼이 필요 없나?

그렇지 않습니다. uuid_extract_timestamp()로 UUIDv7에서 timestamp를 추출할 수 있지만, 문서는 추출된 timestamp가 실제 생성 시각과 반드시 정확히 같지는 않다고 설명합니다. 업무 시간 기록에는 별도 timestamp 컬럼이 더 명확합니다.

UUIDv7은 항상 UUIDv4보다 좋은가?

아닙니다. UUIDv7은 시간순 성격이 장점인 형식입니다. 생성 시각 노출을 피하고 싶거나, 이미 UUIDv4 기반 정책과 인덱스 설계가 안정적으로 운영 중이라면 UUIDv4를 유지하는 판단도 가능합니다.

PostgreSQL uuidv7()의 핵심은 UUID를 유지하면서도 생성 순서와 정렬 순서의 관계를 더 자연스럽게 만드는 것입니다. 새 테이블에서 UUID 기본키를 설계하고 있고 PostgreSQL 18 이상을 기준으로 삼을 수 있다면 DEFAULT uuidv7()은 검토할 만한 선택입니다. 다만 정확한 시간 기록, 유일 제약, 생성 책임의 위치는 별도로 설계해야 합니다.

반응형

'프로그래밍 > 서버, DBMS' 카테고리의 다른 글

PostgreSQL pipeline mode 기준  (0) 2026.09.18
PostgreSQL AIO 기준  (0) 2026.09.18
PostgreSQL skip scan 기준  (0) 2026.09.15
PostgreSQL MERGE RETURNING 기준  (0) 2026.09.15
PostgreSQL keepalives 기준  (0) 2026.08.22
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사