본문 바로가기
츄Log/기타 끄적

ULID (Universally Unique Lexicographically Sortable Identifier)

by 츄츄🦭 2024. 1. 31.
728x90

 

 

유일성을 보장히는 식별자를 만드는 방법은 다양합니다.

그 중 UUID는 많이 들어보았을 것입니다. 

 

> UUID는 128bit으로 표현하는 중복되지 않는 식별자를 만들기 위한 표준 규약입니다. (중복 확률이 0은 아니지만 0에 가깝습니다) 

UUID는 128bit을 16진수로 표현한 32개의 문자로 이루어져 있습니다 (규약대로 하이픈을 추가하면 문자열로 봤을 때는 36자입니다)

 

UUID와 비슷하지만 조금 다른 것이 있는데 그것이 바로 ULID 입니다.


ULID는 Timestamp와 Randomness로 구성되어 있습니다.

 

ULID의 특징은 다음과 같습니다.

  • 128-bit compatibility with UUID
  • 1.21e+24 unique ULIDs per millisecond
  • Lexicographically sortable!
  • Canonically encoded as a 26 character string, as opposed to the 36 character UUID
  • Uses Crockford's base32 for better efficiency and readability (5 bits per character)
  • Case insensitive
  • No special characters (URL safe)
  • Monotonic sort order (correctly detects and handles the same millisecond)

문서에 나와있듯이 ULID는 가장 왼쪽에 Timestamp값을 가지고 있어서 UUID의 단점인 자료구조에서의 fragmentation을 보완할 수 있습니다.

비록 timestamp값이 같다면 오른쪽 Randomness에서 정렬이 보장되지는 않지만 그래도 UUID에 비하면 확실히 fragmentation을 방지할 수 있고, 데이터베이스의 id값으로 들어간다면 UUID에 비해 데이터 shift 문제가 굉장히 완화될 것 같습니다.

(완화 뿐만 아니라 UUID를 키로 사용하는 건 말이 안돼도 임의의 랜덤한 값을 사용하고 싶을 때 ULID를 사용하는 건 괜찮을 것 같네요!) 

 

동일한 timestamp 내에서 monotonicty라는 개념으로 정렬순서를 보장하려고 노력합니다.

monotonicty는 동일한 밀리초가 감지되면, ranomness는 최하위 비트에서 1비트씩 증가됩니다. 

매우 드물게 동일한 밀리초 내에 2^80개가 넘는 ULID를 생성하거나 randomness가 오버플로우가 발생한다면 생성이 실패되기도 합니다.

// monotonicity 
import { monotonicFactory } from 'ulid'

const ulid = monotonicFactory()

// Assume that these calls occur within the same millisecond
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRZ
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0


// 생성 실패
import { monotonicFactory } from 'ulid'

const ulid = monotonicFactory()

// Assume that these calls occur within the same millisecond
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRY
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVRZ
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS0
ulid() // 01BX5ZZKBKACTAV9WEVGEMMVS1
...
ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZX
ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZY
ulid() // 01BX5ZZKBKZZZZZZZZZZZZZZZZ
ulid() // throw new Error()!

 

728x90