관계형 데이터베이스(RDB, Relational DataBase), 정규화(Normalization), 반정규화(Denormalization), 그리고 NoSQL 에 대한 고찰

관계형 데이터베이스(RDB, Relational DataBase), 정규화(Normalization), 반정규화(Denormalization), 그리고 NoSQL 에 대한 고찰

Summary

부트캠프 스터디원 분이 간단하게 스크럼에서 발표했던 내용을 매우 인상적으로 들었는데, 해당 부분에 대해 제가 개인적으로 생각하고 있던 부분들을 휘발시키지 않고 Archiving 해두기 위해서 본 포스트를 작성하게 되었습니다.
관계형 데이터베이스(RDB, Relational DataBase) 에서 정규화(Normalization) 는 이상적인 설계 원칙이지만, 현실적인 성능 요구(특히 Read 중심 시스템) 에서는 반정규화(Denormalization) 가 필요한 경우가 많습니다.
반정규화는 데이터 정합성(Consistency) 유지라는 과제를 동반하며, 이를 해결하기 위해 Transaction 과 Trigger 나 Service Layer 의 보완이 반드시 필요합니다. 개인적으로, 반정규화는 Caching 혹은 Memoization 기법과 유사하다고 느꼈으며, Read 성능이 극도로 중요한 상황에서는 반정규화를 충분히 수행하던지, 아예 NoSQL 을 고려하는 것도 하나의 방향이라는 생각을 했습니다.
다만, 이는 저의 개인적인 생각일 뿐, 더불어 관계형 데이터베이스에 대한 학습이 아직 충분하지 않기 때문에, 이 포스트의 내용은 향후 학습, 실습, 경험 등을 통해 변경되거나 수정될 수 있다는 점을 감안하고 읽어주시기 바랍니다.
 

정규화와 반정규화에 대한 개인적인 생각

관계형 데이터베이스의 설계에 있어 정규화는 중복되는 데이터를 제거하고 데이터의 정합성 혹은 일관성과 무결성을 보장하는 데 이상적인 접근 방식입니다. 이론적으로 보면 정규화를 최대한 적용하는 것이 관계형 데이터베이스 설계의 궁극적인 목적처럼 보이기도 합니다.
하지만 현실적으로는 항상 정규화를 최우선으로 삼는 것이 답이 되지는 않습니다. 특히, 데이터를 조회(Read) 하는 비율이 높은 시스템에서는 정규화된 구조가 성능 병목의 원인이 될 수 있기 때문입니다. 많은 조인(Join) 이 필요한 설계는 결국 I/O Cost 와 Query 복잡도를 증가시키기 때문입니다.

반정규화의 필요성과 주의점

이러한 상황에서는 우리는 반정규화를 고려하게 됩니다. 반정규화는 중복된 데이터를 일부 허용하면서도, Read 성능을 높이기 위한 전략입니다. 그러나 이 과정은 단순한 Table 구조 변경뿐만이 아니라, 데이터 정합성을 유지하기 위한 다양한 조치가 수반되어야 합니다.
예를 들어, 중복된 데이터를 일관되게 관리하려면 기본적으로 Transaction 을 통한 원자성 보장이 선행되어야 합니다. 그리고 구체적인 연결은 다음과 같은 방식을 사용할 수 있습니다.
  • 트리거(Trigger) 같은 SQL Native 기능을 통해 변경사항을 자동 반영
  • 서비스 레이어(Backend Logic) 에서 직접 Logic 처리
이 과정에서 트랜잭션은 특히 중요합니다. 데이터 정합성을 유지하기 위해서는 특정 작업이 실패했을 때 롤백(Rollback) 이 보장되어야 하며, 이는 복잡한 CUD(Create, Update, Delete) 로직에서 필수적인 요소이기 때문입니다. 만일 이게 금전적인 부분과 직결된 문제라면, 실제 피해가 발생했을 때 복구하기 힘든 어마어마한 재앙이 될 수 있습니다.

반정규화 원리에 대한 생각

개인적으로, 반정규화는 결과적으로 캐싱(Caching) 혹은 메모이제이션(Memoization) 을 활용하는 방식과 비슷하다는 느낌을 받았습니다. 중복을 허용하면서도 빠른 접근을 위해 데이터를 특정 위치에 복사하는 전략이 유사하게 느껴졌기 때문입니다. 저장되는 양을 늘리는 것으로 조회의 성능을 끌어올리는 전략이라는 것이죠. 물론, 이 두 기법은 구현 목적과 계층(Layer) 이 다르지만, 속도 향상을 위한 데이터 중복 이라는 공통점이 존재한다는 생각을 했습니다.

RDB 가 아닌 다른 구조의 Database 에 대한 생각

데이터 정합성보다 조회 성능이 절대적으로 중요하거나, 데이터의 규모가 다소 크고 데이터의 구조(Schema) 가 자주 바뀌는 상황이라면, RDB 보다는 MongoDB 같은 컬렉션(Collection) 기반의 NoSQL 계열의 데이터베이스가 적합할 수 있다고 생각합니다.
데이터의 규모가 굉장히 큰 빅 데이터를 관리해야 되는 상황이라면 벡터(Vector) 데이터베이스가 좋은 선택이 될 수 있다는 생각도 들었습니다.
더 나아가, 현실적으로 서비스는 여러 목적이 혼합된 경우가 대부분이기 때문에, 여러 Server 를 두고, 이를 통합하는 기술에 집중하는 것이 궁극적으로 성능 최적화나 장애 대응에 있어 가장 좋은 선택지가 될 수 있지 않을까 하는 생각을 했습니다.
 

마지막으로…

관계형 데이터베이스와 데이터 설계에 대한 저의 이해는 아직 부족한 부분이 많습니다. 이 포스트를 작성한 목적은 제가 생각했던 것들이 휘발되는 것을 조금씩 덜어보고자 하는 목적이 컸고, 담긴 내용 역시 현재까지의 학습을 바탕으로 정리한 개인적인 의견입니다. 향후 더 깊이 공부해 나가면서 수정되거나 보완될 수 있다는 점을 감안하고 읽어주시면 감사하겠습니다.
데이터베이스 설계는 언제나 트레이드 오프(Trade-off) 의 문제라고 생각합니다. 정규화와 반정규화, 여러 Database 들 사이에서 어떤 선택이 최적인지는 결국 문제의 성격과 우선순위에 따라 달라진다는 것은 확실히 말할 수 있습니다. 앞으로 더 많은 사례와 이론을 접하면서 보다 균형 잡힌 시각을 갖고 싶은 마음에 이렇게 포스트를 짧게나마 작성해봤습니다.
 

끗!