이번에 새로운 프로젝트를 진행하면서 ERD 설계를 하는 데 있어서 PK 설정 방법을 고민하게 되었다.
이전에는 아무 생각 없어 MySQL의 AUTO_INCREMENT 기능을 이용해서 편리하게 PK를 잡았었는데, 예전에 어떤 분이 UUID로 PK 바꾸는 것을 고민하셨던 기억이 떠올랐다.
그러면 AUTO_INCREMENT와 UUID의 차이가 무엇이 있고 내가 어떤 걸 왜 선택했는지 말해보고자 한다.
AutoIncrement
가장 보편적으로 PK를 설정하는 방법이다.
MySQL에서는 AUTO_INCREMENT 속성을 통해 자동 증가 옵션을 줄 수 있다.
마냥 편해 보이는 AUTO_INCREMENT에는 무슨 문제점이 숨어 있을까?
1. 값을 유추할 수 있게 된다.
1씩 증가하는 정수 타입을 주게 되는데, 이러한 장점 때문에 역으로는 다음 데이터의 PK를 쉽게 유추할 수 있는 문제가 있다.
(내가 경험했던 사례를 소개하자면 이전에 자체 사이트로 채용을 진행했던 모 사이트에서는 URL에 게시글 PK를 AUTO_INCREMENT로 줘서 숫자만 바꿔서 다른 사람의 면접 일정을 전부 까볼 수 있었다. -> 문의 메일까지 보내놨지만 아직도 수정 안 했더라...)
2. 다중 DB에서 PK 충돌 문제
다중 서버 환경에서 각 서버가 별도의 DB를 운영할 경우 서버에서 생성된 PK가 충돌되는 문제가 발생할 수도 있다고 한다.
이 부분까지는 생각하지 못했지만 DB를 따로따로 관리한다고 하면 충분히 발생할 수 있는 문제라고 생각했다.
UUID(Universally Unique Identifier)
128비트의 크기를 가지는 식별자로 전 세계에서 고유한 식별자를 만들기 위해 표준화된 방법이라고 한다.
16 바이트의 크기를 가지기 때문에 AUTO_INCREMENT와 비교해 최대 16배 큰 값을 다룰 수 있다.
MySQL에서는 아래 쿼리로 UUID를 생성할 수 있다.
INSERT INTO test(test_pk)
VALUES (UUID());
UUID의 가장 큰 장점은 보안이라고 생각한다.
물론 전 세계에서 유일한 식별자를 생성할 수 있다고 하지만 경우의 수를 계산하면 결국 중복이 발생할 수도 있다.(UUID 4 버전의 경우 실제로 충돌할 가능성이 거의 없다고 한다.)
그럼에도 불구하고 UUID를 사용하는 이유는 유추하기 어렵다는 장점이 있다. (실제 PK를 사용할 때 AUTO_INCREMENT 대신 UUID를 URL에 집어넣었다면 위에서 소개한 보안 사고는 발생하지 않았을 것이다.)
(사실 URL에 그런 값을 배치하는 것 자체를 빼버리면 되는데)
그럼 단점은 무엇이 존재할까?
1. 인덱스
UUID는 랜덤하게 생성되기 때문에 인덱스 처리 성능이 AUTO_INCREMENT에 비해 다소 떨어질 수 있다.
AUTO_INCREMENT의 경우 순차적으로 증가되기에 인덱스 생성 시에 B-Tree 구조에 맞게 정렬되지만 UUID의 경우 랜덤하게 생성되기에 성능이 다소 떨어질 수 있다.
2. 저장 공간
데이터가 많으면 많아질 수록 AUTO_INCREMENT의 비해 용량을 배로 차지하게 되는 문제가 생긴다.
그러면 어떤 경우에 AUTO_INCREMENT를 쓰고 어떤 경우에 UUID를 쓰면 좋을까?
우선 AUTO_INCREMENT는 소규모의 프로젝트나 단일 서버에서 사용하는 것이 좋다고 생각한다.
서버가 하나기에 고유한 PK를 쉽게 관리할 수 있고 그에 따라 성능 문제도 덜 발생할 것이라 생각한다.
또 데이터가 순차적으로 필요한 경우도 적합할 것 같다. 삭제가 되지 않는 데이터지만 어떤 시간 순으로 증가하는 무언가가 필요할 때? 사용하면 좋을 것 같다.
반면에 UUID는 대규모 프로젝트나 보안이 중요한 곳에서 사용하는 것이 좋다고 생각한다.
UUID는 128비트 이기에 다른 값을 유추하기 어렵게 만들어 보안 사고를 예방할 수 있는 큰 장점이 있다.
또한 데이터가 수십억을 넘어가는 경우 AUTO_INCREMENT만으로는 한계가 발생할 수 있다. 이런 경우는 UUID를 사용해서 더 큰 범위를 처리하도록 설계하는 것도 좋은 방법이 될 것이다.
그래서 나는 위 내용을 정리했을 때 대부분의 PK는 AUTO_INCREMENT를 사용하기로 결정했다.
소규모 프로젝트의 단일 서버이기도 하고 UUID를 사용할 만큼 보안성을 챙겨야 할 프로젝트는 아니라고 판단했다.
테이블마다 PK의 정책은 달라질 수 있다. 무조건 AUTO_INCREMENT, UUID가 아닌 본인 테이블의 성격에 맞춰서 PK 정책을 설정하는 것도 설계 역량이고 개발 역량이라고 생각한다.
'기타' 카테고리의 다른 글
특정 사용자의 IP만 허용시키기 위한 IP 필터 제작하기 (0) | 2024.11.06 |
---|---|
마이바티스 H2를 이용한 통합 테스트 환경 구축 방법 (1) | 2024.10.03 |
API에 대한 로깅을 어떻게 찍는 게 좋을까?(인터셉터, 필터, AOP) (0) | 2024.09.15 |
SSAFY를 수료하고 7개월만에 취업 (취준 1년 7개월) (7) | 2024.07.24 |