-
GUID대신 ULID를 사용해 보자.프로그래밍 2024. 10. 23. 11:39
고유 식별자는 엔터티를 고유하고 일관되게 구별하기 위한 소프트웨어 개발에 필수적이다.
가장 일반적인 유형으로는 GUID, UUID 및 ULID가 있다.
이 문서에서는 GUID, UUID 및 ULID에 대한 차이점과 ULID를 추천하는 이유에 대해 설명한다.
주된 이유는 ULID는 난수 임에도 시간 정렬이 가능하다는 것이다.
GUID(Globally Unique Identifier, 전역 고유 식별자)
개요
- GUID는 Globally Unique Identifier의 약자.
- 컴퓨터 시스템의 정보를 고유하게 식별하는 데 사용되는 128비트 숫자.
- Microsoft 기술에서 일반적으로 사용.
판
- 표준 형식: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- 본보기: 123e4567-e89b-12d3-a456-426614174000
특성
- 임의성: 주로 난수 또는 의사 난수를 기반으로 함.
- 고유성: 매우 독특하지만 시간 순서가 지정되지 않음.
- 가독성: 사람이 읽을 수 없음.
사용 사례
- 데이터베이스 키.
- 분산 시스템의 식별자.
- .NET 응용 프로그램.
장점
- 매우 높은 고유성.
- 다양한 프로그래밍 언어 및 플랫폼에서 널리 지원.
단점
- 연대순이 없음.
- 크기가 더 커서 스토리지 및 인덱싱 성능에 영향을 줄 수 있음.
ULID(Universally Unique Lexicographicically Sortable Identifier, 보편적으로 고유하게 사전적으로 정렬할 수 있는 식별자)
개요
- ULID는 Universally Unique Lexicographically Sortable Identifier의 약자.
- 정렬 가능하고 고유하게 설계.
판
- 표준 형식: 01AN4Z07BY79KA1307SR9X4MV3
- 본보기: 01ARZ3NDEKTSV4RRFFQ69G5FAV
특성
- 시간 기반: 48비트 타임스탬프와 80비트 임의 구성 요소를 인코딩.
- 정렬 가능성: 사전 편찬으로 정렬할 수 있으며, 이는 생성 시간을 기준으로 정렬할 수 있음을 의미.
- 가독성: GUID 및 UUID에 비해 사람이 더 쉽게 읽을 수 있음.
사용 사례
- 이벤트 로그.
- 순차적 정렬이 필요한 데이터베이스.
- 정렬 가능한 고유 식별자가 필요한 분산 시스템.
장점
- 사전 순으로 정렬 가능.
- 시간 기반 접두사.
- 더 나은 가독성.
단점
- GUID 및 UUID보다 최신이며 널리 지원되지 않습니다.
- 자동 증가 정수와 같은 더 간단한 ID에 비해 큽니다.
GUID는 특히 Sql Server에서 채번하는 GUID는 그 형태에서 그룹요소가 발생한다.
따라서, DB 마이그레이션이 발생하는 경우 KEY 정렬을 수행할 때 매우 복잡한 상황이 발생할 수 있고, 그룹요소가 깨질 경우 마이그레이션이 불가능 하게 된다. 또한 정렬 성능도 그 크기에 의해 매우 떨어지게 된다.
필자가 ULID를 추천하는 이유는 해당 ID가 시간을 기반으로 생성하는 정렬 가능한 ID 이기 때문이다.
만약 ULID를 사용하기로 하였다면 DB 채번이 아닌 Application 채번이 될 것 이기에 기존 DB 채번에 익숙하다면 혼란할 수 있지만, 정수 KEY가 아닌 ULID를 사용한다면, 특히 멀티 테넌트의 경우에는 효과적으로 DB KEY를 다루기가 편해질 수 있다.
닷넷에는 NUlid가 있다.
RobThree/NUlid: .Net ULID implementation
NUld를 사용할 경우 loop에서 채번을 하면 시간순 정렬이 되지 않는 경우가 있다.
이러한 경우를 위해 RNG를 사용하게 되는데 코드는 아래와 같다.
public class UlidGenerator { private static Lazy<UlidGenerator> _instance = new Lazy<UlidGenerator>(() => new UlidGenerator()); public static UlidGenerator Instance => _instance.Value; private UlidGenerator(){} private MonotonicUlidRng _rng = new MonotonicUlidRng(); public Ulid Generate() => Ulid.NewUlid(_rng); public string GenerateString() => Ulid.NewUlid(_rng).ToString(); public Ulid Generate(DateTimeOffset offset) => Ulid.NewUlid(offset); }
위 코드에서는 기본적으로 모두 RNG를 사용하게 하였다.
RNG는 동일한 밀리초 내에 ULID를 생성할 때 정렬 순서와 관련하여 몇 가지 보장을 제공할 수 있는 기능으로 Loop에서 채번을 해야 한다면 위 코드를 참고하면 되겠다.
만약, GUID 이슈로 고통받고 있다면 ULID를 사용해 보자.
도움이 되기를 바라며...
'프로그래밍' 카테고리의 다른 글
시계열 데이터를 전송하는 방법 (0) 2024.10.25 사용자 Session을 처리하는 방법 (1) 2024.10.24 AntdUI 소개 (1) 2024.10.22 리소스 관리 전략 (0) 2024.10.22 Json을 통한 Kafka ObjectId에 대한 처리 (0) 2024.10.21