🤔 고민
블로그를 위한 ERD 설계 과정에서 UUID와 auto increment 중에 무엇을 PK로 선택해야할지에 대해 고민이 생겼다.
UUID(Universally Unique Identifier)란?
네트워크상에서 고유성을 보장하는 ID를 만들기 위한 표준 규약
- 128bit의 고유 식별자
- 다른 고유 ID 생성 방법과 다르게 UUID는 중앙 시스템에 등록하고 발급하는 과정이 없어서 상대적으로 더 빠르고 간단하게 만들 수 있음
- 중복될 확률이 매우 낮음 (10억 분의 1)
UUID 구조
- 128-bit의 숫자 문자열이며 총 길이는 36자리
- 32개의 16진수 숫자
- 4개의 하이픈(-)으로 나누어진 8-4-4-4-12 형태
- 하이픈 사이 16진수 숫자들 = 하나의 필드
- 각 필드는 정수로 취급되며 가장 중요한 숫자가 앞에 나옴
ex) 3번째 필드의 첫 숫자 = 4 = UUID 버전
UUID 버전
- 버전 1, 2
- 보통 타임스탬프 UUID라고 부름
- 해당 버전의 UUID는 만들어진 시점과 기기 정보를 알 수 있음
- 버전 3, 5
- 네임스페이스 기반으로 만드는 UUID
- 네임스페이스를 해싱 알고리즘으로 암호화해서 UUID 생성
- 해당 버전의 UUID는 다른 정보와 연결된 값을 만들고 싶을 때 사용하면 좋음
- 버전 4
- 가장 흔히 사용하는 버전
- 다른 버전과 달리 외부 정보에 의존하지 않고 완전히 랜덤한 값으로 생성됨
=> 어디서 어떻게 생성됐는지 알 수 없음 - 보안 측면에서 뛰어나고 생성도 빠르기 떄문에 대중적으로 사용됨
JAVA에서 UUID 만드는 방법
- UUID 클래스의 randomUUID() 호출하면, 버전 4 UUID 값을 가진 객체가 return
import java.util.UUID;
UUID.randomUUID().toString();
그렇다면 PK로 auto increment와 UUID 중 무엇을 선택하는 것이 좋을까?
PK로 auto increment 선택하는 경우
장점
- 구현이 쉬움
- 정렬 속도가 빠름
- 로그 분석 시, 의미 파악하기 쉬움
단점
- 분산 환경에서 확장이 어려움
- 보안 관점에서 불리함
auto increment는 1,2,3,... 처럼 순차적으로 숫자가 정해지므로 외부에서 데이터를 가져가기 좋다는 문제점이 있다. 예를 들어, 조회 API에서 auto increment PK를 사용한다면, 쉽게 해당 API를 통해 데이터를 가져갈 수 있다.
또한, auto increment를 사용할 경우, 외부에서 PK값을 통해 해당 서비스의 규모를 추정할 수 있다.
PK로 UUID 선택하는 경우
장점
- UUID 생성이 간단함
- 분산 환경에서 규모 확장이 쉬움
단점
- 128-bit이므로 저장공간을 많이 차지함
- 의미 파악이 힘듦
- 정렬로 인한 성능 저하 발생
PK는 기본적으로 Clusterred Index로 쓰인다. Clustered Index는 테이블의 데이터를 지정된 컬럼에 대해 물리적으로 데이터를 재배열 한다. 이때, UUID는 128-bit의 문자열이므로 UUID를 정렬하는 것은 auto increment를 정렬하는 것보다 성능이 좋지 않다.
결론
1. 각각의 장단점을 생각하여 상황에 따라 적절한 것을 선택하자.
2. auto increment와 UUID 모두 사용하자.
테이블의 PK는 auto increment를 사용하고, UUID를 저장할 칼럼을 추가하여 auto increment로 데이터 관계를 관리하도록 하고 ID를 외부에 노출시켜야 하는 경우에 UUID를 사용한다. 이때, UUID는 사용자 친화적이지 않으므로 UUID를 그대로 사용하는 것이 아닌 slug를 사용하여 URL을 친화적으로 만드는 것이 좋다. 만약 slug가 중복된다면, 뒤에 해시값을 붙여 대체 식별자를 만들 수 있다.
- slug = 웹 사이트의 특정 페이지를 쉽게 읽을 수 있는 형태로 식별하는 URL의 일부
📚 참고자료
'개발 일지' 카테고리의 다른 글
[SSAFY] OAuth2.0 + Spring Security (+ token을 어떻게 전달할까?) (2) | 2024.05.27 |
---|