Globally unique identifier
전역 고유 식별자(全域固有識別子, 영어: Globally Unique Identifier, GUID)는 응용 소프트웨어에서 사용되는 유사 난수이다. GUID는 생성할 때 항상 유일한 값이 만들어진다는 보장은 없지만, 사용할 수 있는 모든 값의 수가 2^128 = 3.4028×10^38개로 매우 크기 때문에, 적절한 알고리즘이 있다면 같은 숫자를 두 번 생성할 가능성은 매우 적다.
GUID는 오라클 데이터베이스 등 많은 곳에서 쓰이지만, 가장 눈에 띄는 구현은 아마도 마이크로소프트의 구현일 것이다. 표준으로는 오픈 소프트웨어 파운데이션(Open Software Foundation, OSF)이 지정한 범용 고유 식별자(Universally Unique Identifier, UUID)가 있다.
리소스의 ID, GUID로 할까 Sequential로 할까?
특정한 리소스를 고유하게 지정하는 ID를 어떻게 만들 것인가 하면 보통은 크게 2가지 방법을 주로 쓰는 걸로 압니다. 하나는 DB 테이블의 Primary Key에 Auto Increment를 걸어서 나오는 순차적인 정수값을 그대로 써먹는 것이고, 다른 하나는 랜덤한 128비트 값인 GUID(UUID라고도 함)를 그때그때 생성하여 사용하는 방식입니다.
웹에서 볼 수 있는 수많은 서비스들의 데이터는 RDBMS가 상당수 책임지고 있고, 이런 DBMS의 Auto Increment는 내부적으로 최적화되어 있을 뿐더러 사용하는 개발자 입장에서 이해하기도 예측하기도 쉽고 데이터가 들어온 순서대로 정렬하는 것도 간단합니다. 그저 숫자를 1씩 더해갈 뿐이니까요. 하지만 이 방법은 특정한 경우 보안상 노출되지 않았으면 하는 정보를 외부에 노출할 수 있다거나 (예를 들면 경쟁사에서 우리 서비스의 사용자 숫자 등 주요 지표를 쉽게 눈치챌 수 있음) 또는 분산형 아키텍쳐에서 문제가 될 수 있는 등의 문제점이 있습니다.
GUID를 사용하는 방법은 위와는 특징이 정반대입니다. GUID는 다른 의존성 없이 충돌가능성이 0에 가까운 사실상 고유한 128비트 값을 그때그때 만들어 사용하기 때문에, 분산형 아키텍쳐에서도 아무런 문제가 없을 뿐더러 외부에 다른 유의미한 정보를 뜻하지 않게 흘릴 우려도 없습니다. 그러나 랜덤하게 생성된 값을 RDBMS에 쓰는 것은 성능 저하를 불러올 수 있으며, 또한 그 자체로는 데이터가 들어온 순서대로 정렬하는 것도 불가능합니다. 이러한 약점을 보완하고자 완전한 랜덤이 아니라 시간 정보가 가미되어 불완전한 순차성을 띄는 Timeflake와 같은 것을 사용하는 경우도 있습니다. 제가 직접 써본 적은 없지만, Laravel 같은 프레임워크에서도 이런 방식을 쓴다고 하더라고요.
보완책인 ULID 를 사용할 수도 있다.