데이터베이스 설계에서 기본 키(Primary Key) 선택은 시스템의 성능, 확장성, 그리고 데이터 무결성에 큰 영향을 미치는 중요한 결정입니다. PK를 바꾼다는 것은 꽤나 번거로운 작업이기에 나중에 확장하기 쉽거나 어렵게 만드는 결정을 끊임없이 내리게 됩니다.
기존에 프로젝트를 진행하면서 RDB 테이블의 PK의 경우 대부분, 데이터베이스의 auto increment ID 생성 전략에 위임하고 신경 쓰지 않는 경우가 많았습니다. 최근 supabase로 토이 프로젝트를 진행하면서 PostgreSQL의 PK 생성 옵션으로 auto increment와 UUID 중 선택할 수 있었는데, 여기서 UUID를 PK로 사용하는 것의 장점을 살펴보고, 토이 프로젝트에 UUID를 적용하는 것이 적절할지 고민해보겠습니다.
먼저 UUID의 정의와 장단점에 대해서 살펴보겠습니다.
UUID
UUID는 전 세계적으로 고유성을 보장하는 128비트 식별자입니다. 주로 데이터베이스의 Primary Key나 분산 시스템에서 고유한 식별자를 필요로 할 때 사용됩니다. 다양한 버전이 있지만, 무작위로 생성되는 V4가 가장 많이 사용됩니다.
장점
- 글로벌 고유성:
- UUID는 전 세계적으로 고유한 값을 보장합니다. 이는 여러 시스템이나 데이터 소스 간에 중복되지 않는 식별자를 제공하는 데 유용합니다.
- 분산 시스템에서의 유용성:
- 여러 노드에서 독립적으로 UUID를 생성할 수 있으므로, 중앙 서버 없이도 고유성을 유지할 수 있습니다. 이는 분산 시스템에서 특히 유용합니다.
- 보안 강화:
- UUID는 길고 복잡한 문자열로 구성되어 있어 예측 불가능합니다. 이는 외부 공격자가 식별자를 추측하는 것을 어렵게 만듭니다.
- 데이터 통합 용이성:
- 다양한 데이터 소스를 통합할 때, UUID는 고유성을 유지하여 데이터 충돌을 방지할 수 있습니다.
단점
- Increment PK에 비해 저장 공간을 더 많이 사용합니다.
- 인덱스 성능이 상대적으로 낮을 수 있습니다.
UUID를 사용하면 여러 서버에서 동시에 ID를 생성해도 충돌 걱정이 없어, 분산 시스템에서 특히 유용합니다. 하지만 저장 공간과 인덱스 성능을 고려해야 합니다. 특히 PK가 많은 RDB에서 클러스터형 인덱스로 자동 생성되는데, 완전 랜덤으로 생성되는 UUID V4의 특성상 새 레코드의 삽입이 비효율적일 가능성이 크고, DB 내부 캐시 효율성, 범위 쿼리의 효율성 또한 떨어질 것으로 보입니다.
고려 사항
UUID를 사용해야만 하는 이유와 Increment PK와의 비교를 통해 더 깊이 고민해 보았습니다.
- Increment PK를 사용하여, URL로 노출되면 예측하기 쉬워, 보안상 문제가 생길 수도 있다?
- 다른 블로그나 인터넷 글에서 API가 /user/{pk}/ 이런 URL 패턴으로 구성되어 있을 경우, 다른 고객의 정보가 쉽게 노출될 수 있다며, UUID를 써야 한다는 글이 많았습니다. 물론, Increment ID의 경우 예측하기 쉬운 것은 사실이지만, 적절한 인가 정책과 보안이 설정되어 있다면 이 부분은 문제가 되지 않을 가능성이 큽니다. UUID의 경우에도 결국 노출되는 것은 마찬가지이며, UUID만으로 접근 권한을 부여하는 방식은 보안상 적절하지 않습니다. RFC 4122에 따르면, 데이터의 총 컬럼 수 자체를 숨기는 케이스가 아니라면, 해당 이유로 UUID를 선택하기보다는 적절한 인가 정책과 함께 Increment PK를 사용하는 것이 더 적절합니다. (GitHub의 예를 참고해 보세요)
- 확장성, 차후 분산 시스템을 고려했을 때는, Increment PK에는 한계가 있다?
- 이 부분은 맞는 말입니다. 다만, 토이 프로젝트라는 특성을 고려했을 때, 확장성을 무한대로 고려할 필요가 없기도 하고, 주로 확장을 한다고 하더라도 어플리케이션과는 다르게 DB는 Scale Up을 하는 경우가 많기 때문에 괜찮다고 생각했습니다. 물론, 서비스나 트래픽의 규모가 늘어났을 경우에는 DB에서보다 어플리케이션에서 ID를 생성해야 할 수도 있고, Scale Out을 고려해야 할 수도 있기 때문에, 이 부분은 인지하고 있어야 합니다.
- 데이터 마이그레이션 및 통합의 용이를 위해서는 UUID가 적합하다?
- 마찬가지로 토이 프로젝트 단계에서는 고민할 단계가 아니라고 생각했습니다.
결론
이와 같은 흐름을 거쳐 토이 프로젝트의 PK 값은 Auto Increment가 조금 더 적절하다는 판단을 내리게 되었습니다. 물론, 데이터의 특성에 따라서(API 키를 제공한다던지, 거래 시스템, 트랜잭션, 세션, 다운로드 등) UUID를 활용할 만한 부분도 있지만, 대부분의 테이블을 설계할 때는 Auto Increment를 사용해 정수형 PK를 사용했습니다.
UUID의 사용 시 부작용이 생각보다 크기 때문에, 대규모 데이터를 다루는 프로젝트에서도 무작정 UUID를 도입하기보다는, 요구 사항과 데이터의 특성을 잘 분석하여 UUID V7, Snowflake 혹은 자체 식별자 생성 등 다양한 요소를 비교하여 사용하는 것이 바람직할 것 같습니다.
참고 자료
'개발 > CS' 카테고리의 다른 글
버퍼(Buffer)에 대한 이해와 활용 (0) | 2024.06.07 |
---|