UUIDv7을 쓰는 주된 이유는 정렬된 키가 B-트리 인덱스의 캐시 지역성을 높여주기 때문임. 이 효과를 얻는 데 이런 속성들이 엄격하게 보장될 필요는 없음.
내가 사용하는 핵심 이유도 이것인데, 글에서는 전혀 다루지 않음. Postgres가 기본 키에 해시 인덱스를 사용할 수 있다면 굳이 v7을 쓰지 않을 것임.
일부 식별자를 UUIDv7으로 바꿔 타임스탬프 대신 ID로 테이블을 파티셔닝하고 싶음. 현재는 일정 기간의 데이터만 유지하면서 비용이 큰 VACUUM 없이 오래된 데이터를 저렴하게 삭제하려고 타임스탬프 기준으로 파티셔닝함.
단점은 UUIDv4로 항목을 조회할 때 모든 파티션을 검색해야 할 수도 있다는 것임. UUIDv7이면 partition pruning을 활용해 관련 파티션만 조회할 수 있음.
단조 증가가 필요해서 UUIDv7을 선택한 사람을 실제로 만나본 적은 없는 것 같음. 물론 아직 만나보지 못한 사람도 많을 것임.
예를 들어 TigerBeetle은 클라이언트에서 생성하는 멱등성 ID로 something similar to UUIDv7을 권장함. 여러 네트워크 계층의 재시도로 이중 지출이 발생하지 않도록, 데이터베이스는 각 송금이 최대 한 번만 실행되도록 보장해야 함. 웹사이트나 모바일 앱이 송금 ID를 로컬에서 생성하면 데이터베이스는 같은 ID를 전에 본 적이 있는지 확인해야 하는데, 송금 이력이 10년 치라면 매우 느려짐.
하지만 ID가 클라이언트의 로컬 시간 등을 기준으로 대체로 단조 증가한다면, 최근 하루 치 ID만 메모리에 유지하는 식으로 멱등성 검사를 빠르게 처리할 수 있음.
UUIDv7 명세는 문자열이나 바이트 슬라이스로 ID를 비교하기 좋은 빅 엔디언을 사용함. 우리는 ID를 u128 숫자로 비교하려 하므로 리틀 엔디언을 사용함.
클라이언트에서 생성하는 ID는 실제로 단조 증가하지 않으며, 시계 값도 완전히 엉터리일 수 있어 시간을 신뢰할 수 없음. 내부 ID에는 서버 측의 엄격하게 단조 증가하는 u64 타임스탬프를 사용함. 서버에서 ID를 부여하고 데이터베이스가 엄격한 직렬 가능성을 보장한다면 무작위 요소는 전혀 필요하지 않으며, 서버 시계도 신뢰할 수 있게 만들 수 있음.
명세 자체로는 당연히 아무것도 보장할 수 없음. 하지만 잘 만든 구현체는 이런 속성을 상당수 갖출 수 있음.