처음에 프로젝트 시작 전, ERD를 구성할 때는 무결성 유지 때문에 정규화, 비정규화의 개념조차도 모른채 설계를 했다. 하지만 프론트 쪽에서 요구하는 데이터를 모두 한번에 넘겨주는 조회 쿼리를 짜다가 너무 과도하게 Join을 해야하는 경우를 만나면서 처음 DB 설계를 했던 지점으로 다시 돌아가보게 되었다. '과연 처음부터 이렇게 Table 설계를 하는 것이 맞았나?' 고민했다. 하지만 수많은 고민 끝에 나의 대답을 결국 Yes이다. 왜냐하면 우리는 고객이 여행 계획을 짜는 서비스인 특성 상, 데이터의 삽입, 수정, 삭제가 굉장히 빈번하게 발생할 수 밖에 없고 그 과정에서 테이블 간의 데이터 무결성은 반드시 지켜져야 이상현상(Anomaly)이 발생하지 않기 때문이다.
그럼에도 불구하고 대규모 IT 서비스에서 규모 확장성을 요구하는 시스템인 경우, 일반적으로 정규화된 데이터베이스와 비정규화된 데이터베이스를 섞어서 사용하고 있는데 그것 또한 나름의 이유가 있다고 생각한다. 그리고 나 또한 이번에 Join을 10번이나 해야지만 원하는 데이터를 뽑아낼 수 있는 쿼리를 짜면서 이 부분에 대해 깊이 고민했고, 기술적인 문제로 join으로만 데이터를 뽑아내는데 한계가 있는 경우까지 겪었기 때문에 데이터의 정규화와 비정규화에 대해 한번 좀 더 자세히 정리해보고자 한다.
정규화 데이터베이스(Normalized Database)는 중복을 최소화하도록 설계된 데이터베이스를 말한다.
비정규화 데이터베이스(Denormalized Database)는 읽는 시간을 최적화하도록 설계된 데이터베이스를 말한다.
비정규화는 하나 이상의 테이블에 데이터를 중복해 배치하는 '최적화 기법'이다. 시스템의 성능향상, 개발 및 운영의 편의성 등을 위해 정규화된 데이터 모델을 통합, 중복, 분리하는 과정으로 '의도적으로' 정규화 원칙을 위배하는 행위이다.
비정규화의 장점은 바로 1. 빠른 데이터 조회(Join 비용이 줄어들기 때문), 2. 데이터 조회 쿼리의 간단화이다. 나도 실제로 하루종일 조회 쿼리문을 요리조리 바꿔보면서 Join을 10개까지 해보다가, "이게 정말 되는게 맞나?" 싶어서 찾아보다가 비정규화까지 알게 되었으니, 만일 이렇게 Join을 빈번하게 해서 조회되는 쿼리가 많다고 하면 서비스의 버그 발생을 줄이고 성능 개선을 위해 비정규화를 고민해야하는 게 맞는 듯 하다.
하지만 비정규화의 단점은 바로 1. 데이터 갱신이나 삽입 비용이 높음, 2. 데이터의 무결성 해침, 3. 데이터 중복저장으로 인한 추가 저장공간 확보 필요가 있다.
즉 데이터 중복저장으로 인해 이상 현상이 발생할 가능성이 높아지는데 결국 이건 다시 데이터의 정규화로 해결하는 수 밖에 없다. 그래서 자신이 운영하는 비즈니스의 특성을 잘 고려해서 정규화해야 할 데이터와 비정규화해야 할 데이터를 잘 구분하는 능력이 중요하다.
정규화는 관계형 데이터베이스에서 중복을 최소화하기 위해 '데이터를 구조화하는 작업'이다.
정규화은 특정조건을 만족하는 릴레이션의 스키마 형태를 말하는데, 제 1 정규형, 제 2 정규형, 제 3 정규형, BCNF형이 존재한다.
정규화의 장점은 1. 데이터베이스 변경 시 이상현상 제거, 2. 효과적인 검색 알고리즘 생성, 3. 데이터 구조의 안정성, 무결성 유지 등이 있다. 하지만 단점은 1. Join연산의 증가로 응답 시간이 저하된다는 것이다.