적용 방법
의존성
build.gradle에 한 줄 추가해준다.
Entity
Id로 쓸 필드에 @Tsid를 추가해 준다
끝이다...
혹시 몰라 조금 더 설명해 보자면 TSID가 들어가는 Id 필드는 직접 값을 넣지 않고 시퀀스로 자동 할당을 하던 것처럼 그냥 두면 알아서 자동으로 들어간다 혹시 @GeneratedValue(strategy = GenerationType.IDENTITY) 이 비슷하게 생긴 어노테이션이 있다면 지워주자
이거 왜 써?
솔직히 그냥 트위터에서 쓰는 트위터에서 만든 snowflake와 ULID랑 장점 합쳐서 좋아 보여서 가져왔다.
공간 효율성과 대규모 분산 시스템에서 병렬 처리와 고유성을 보장 또 타임스탬프 값이 앞에 배치되어 정렬을 위한 컬럼이 따로 필요가 없어서이다.
비교
다른 할당 방식은 어떻길래 굳이 TSID를 쓰기로 생각했는지 아래 정리해 보겠다.
자동생성
단일 시스템에서는 자동으로 1부터 하나씩 증가 하도록 해도 큰 문제는 없다.
하지만, 대규모 분산 처리 시스템 기본키(PK)를 생성한다면 기본키가 중복으로 생성될 수 있다. (운이 없다면 소규모 시스템 에서도...)
Random()을 이용한 할당
random의 가장 큰 문제는 자원의 낭비가 심하다.
아무리 범위를 크게 잡더라도 중복이 발생할 가능성이 있기 때문에 난수가 중복이 있는지 체크를 해주어야 하고 사용자가 많아지고 서비스 기간이 늘어날수록 중복이 연속으로 3번, 4번 ...N번 발생하지 않으리라는 보장도 없고 이는 서버의 자원을 낭비하게 되는 결과가 발생할 가능성이 높다. 그렇다고 중복을 최소화하겠다고 범위를 매우 크게 잡으면 그거 나름대로 낭비가 심해진다.
또한 id를 난수로 할당하기 때문에 정렬을 위한 컬럼을 하나 추가해야 하기 때문에 이것 또한 낭비라고 생각했다.
비슷한 이유로 16바이트를 차지하고 랜덤인 UUID도 패스했다
ULID
이름만 봐도 UUID와 관련이 있어보인다
UUID은 Universally Unique Identifiers여서 UUID인데 ULID는 Universally Unique Lexicographically Sortable Identifier면서 왜 UULSID가 아니지?
ULID는 48비트의 timestamp와 80비트의 랜덤 한 값으로 이루어져있다.
timestamp가 앞쪽에 배치되어 있어 정렬을 위한 컬럼이 필요 없다는 게 장점이지만 여전히 문자열은 숫자로만 구성되었을 때보다 인덱스에서 삽입 위치를 찾는 것이 더 복잡하고 비효율적일 수 있고, 128비트로 여전히 많은 공간을 차지한다.
TSID
TSID는 snowflake와 ULID의 아이디어를 결합한 것이 TSID이다.
https://github.com/f4b6a3/tsid-creator/
GitHub - f4b6a3/tsid-creator: A Java library for generating Time-Sorted Unique Identifiers (TSID).
A Java library for generating Time-Sorted Unique Identifiers (TSID). - f4b6a3/tsid-creator
github.com
TSID의 장점은
64비트로 UUID, ULID보다 가벼움
정수 사용으로 사용이 편하고 효율적
ULID처럼 timestamp를 사용하여 정렬에 용이
사용이 매우 간단함
등이 있어서 사용하게 되었다
마지막으로
프로젝트 정도는 자동할당으로 쓰는게 편하고 문제도 크게 없을 것 같긴하지만 DB가 2대 이상만 되어도 문제가 생길 가능성이 많이 올라가기 때문에 이왕 하는김에 TSID를 쓰기로 결정 하였고 무엇보다 쓰는 방법이 쉽고 보안적으로나 성능적으로나 신뢰성으로나 훨신 좋아보이기 때문에 쓰기로 하였고 지금까지 auto increment만 쓰던 나한테는 새로운 경험이었다.
'spring' 카테고리의 다른 글
ec2인스턴스에 접근하기 (putty, wsl) (0) | 2024.10.30 |
---|---|
[Trouble Shooting] ec2를 이용한 프로젝트에서 데이터베이스 권한 (0) | 2024.05.18 |