🪪

유일한 ID 생성하기


프론트엔드 개발을 하다보면 여러 요소에 대해 유일한 id 값을 생성해줘야 할 때가 있다. 서버에서 id를 생성하는 경우가 아니라면 어플리케이션에서 적절한 값을 줘야한다. 예를 들어, React에서 map을 통해 여러 컴포넌트를 생성할 때, 각 요소를 구별가능한 key 값을 줘야한다.

이때 어떻게 id를 생성하면 좋을지 알아봤다.

UUID

UUID는 네트워크에서 고유성을 보장하는 값을 만들기 위한 표준규약이다. 분산환경에서 개별 시스템이 id를 발급해도 유일한 값을 보장하기 위해 탄생했다.

UUID는 32개의 16진수(128bit)로 표현되고 총 36개 문자로 8-4-4-4-12의 형태를 가진다.

UUID 버전은 1, 3, 4, 5가 있다.

  • v1: 타임스탬프 기준 생성(+ MAC주소)
  • v3: 'MD5' 사용
  • v4: 랜덤 생성(무작위 uuid)
  • v5: 'SHA-1' 사용

주로 1버전과 4버전이 사용된다고 한다.

사용

UUID를 생성하는 패키지를 받아서 그대로 사용하면 된다.

UUID를 사용하면 자매 요소들간 뿐만 아니라 어플리케이션 전체에서 유일한 값을 가지도록 할 수 있다. 또한 uuid에 타임스탬프를 추가하면 시간으로 정렬도 가능하다.

단점은 uuid를 위한 패키지를 받아야 한다는 점과 너무 길다는 것이다..

MongoDB ObjectID

MongoDB에서 사용하는 id를 참고해보자.

ObjectID는 12바이트 크기의 16진수로 구성된다. 첫 4바이트는 타임스탬프, 다음 5바이트는 랜덤으로 생성된 값, 다음 3바이트는 카운트이며 최초값은 랜덤으로 생성된다.

사용

ObjectID 참고해서 id 생성기를 구현해보자.

1class IDGenerator {
2 #count = 0;
3 getID() {
4 const timestamp = new Date().getTime().toString(16);
5 const randomNumber = Math.floor(Math.random() * 2 ** 20).toString(16);
6
7 const count = this.#count.toString(16);
8 this.#count = (this.#count + 1) % 2 ** 12;
9
10 return timestamp + randomNumber.padStart(5, '0') + count.padStart(3, '0');
11 }
12}

먼저 Date.getTime을 통해 타임스탬프를 얻고 16진수로 바꾼다. 그 다음에는 5자리 16진수 랜덤값, 다음에는 최대 3자리 16진수 카운트를 더해준다. count는 굳이 랜덤으로 시작할 필요가 없다고 생각해서 0부터 시작한다.

백만개까지 생성해봤는데 겹치는 것 없이 잘 동작했다.

실제로는 요소를 백만개까지도 생성할 일은 거의 없을 것이기 때문에 사용할만한 것 같다.

randomNumber는 사실 딱히 필요없을 것 같다. 이 부분은 빼도 무관하다고 생각한다. 오히려 뺌으로써 요소들을 id로만 정렬할 수 있다는 점에서 좋은 것 같다.

마치며

위에서 소개한 내용 외에도 instagram에서 사용하는 방식, twitter의 snowflake도 알아봤는데 한 어플리케이션에서 사용할거면 위 내용으로 충분하다고 생각된다.

한 분야의 알고리즘이 다른 분야의 문제해결에 적용한다는 점에서 CS 공부가 중요하다는 생각을 다시 한 번 느꼈다. 이제 id에 무지성으로 index를 박아넣는 행동은 지양하자.


참조:
https://ko.wikipedia.org/wiki/%EB%B2%94%EC%9A%A9_%EA%B3%A0%EC%9C%A0_%EC%8B%9D%EB%B3%84%EC%9E%90
https://charsyam.wordpress.com/2012/12/26/%EC%9E%85-%EA%B0%9C%EB%B0%9C-global-unique-object-id-%EC%83%9D%EC%84%B1-%EB%B0%A9%EB%B2%95%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC/
https://pegasuskim.wordpress.com/2015/11/06/sharding-key-id-%ec%83%9d%ec%84%b1-%ea%b3%bc-%ea%b4%80%eb%a0%a8-%ec%9d%b4%ec%8a%88/
https://darkstart.tistory.com/147