Table of Contents
데이터 모델링
- 몽고DB는 느슨한 스키마를 지원한다. 그래서 도큐먼트마다 다른 필드를 가질 수 있고, 심지어 필드마다 다른 타입의 데이터를 가질 수도 있다. 그래서 자칫 몽고DB에서 데이터 모델링은 중요하지 않다고 생각될 수도 있다.
- 하지만 몽고DB에서의 데이터 모델링은 RDBMS에서 모델링 만큼이나 중요하다. 왜냐하면 몽고DB에서 데이터 모델링은 성능뿐만 아니라 데이터 일관성, 샤딩 등 다양한 요소에 영향을 끼치기 때문이다
- 몽고DB는 스키마 변경이 자유롭기 때문에, DB서버가 중지되지 않고도 스키마를 바꿀 수 있다. 그래서 몽고DB에서는 어플리케이션의 변화에 맞게 스키마를 반복적으로 변경할 수 있다.
- (하지만 변경 이전의 데이터는 변경된 후의 스키마를 따르지 않기 때문에, 필요한 경우 백엔드단에서 직접 스키마에 맞게 변경되는 스크립트를 실행해줘야 한다)
모델링 팩터
- 데이터를 모델링할 때 데이터를 어느 단위로 분리할지 생각해보자
데이터베이스
- 하나의 몽고DB 인스턴스는 여러 개의 데이터베이스를 가질 수 있고, 각 데이터베이스는 다시 여러 개의 컬렉션을 가질 수 있다
- 몽고DB에서는 데이터베이스 이름과 컬렉션 이름의 조합을 네임스페이스라고 한다
- 서비스의 특성에 맞게 데이터베이스와 컬렉션을 적절히 분리하고 통합해야 성능과 관리의 편리성을 모두 얻을 수 있다
- 몽고DB 초기 버전에서는 도큐먼트 변경 작업이 데이터베이스 글로벌 락을 발생시켰다
- 지금은 WiredTiger 스토리지 엔진 도입으로, 다른 RDBMS와 동등한 수준의 도큐먼트 수준의 잠금을 제공한다
- (하지만 스키마 변경, 관리자 명령, 컬렉션 또는 인덱스 추가/변경과 같이 여전히 데이터베이스의 잠금을 발생시키는 것들도 있다)
- 그래서 데이터베이스 잠금을 발생시키는 작업이 자주 발생한다면 데이터베이스를 작은 단위로 분리하는게 성능상 이점이 있다
- 하지만 대부분의 경우 데이터베이스 분리는 성능보다는 샤딩이나 서비스 통합과 관련해서 많이 고려하는 부분이다
- WiredTiger나 RocksDB 스토리지 엔진을 사용한다면 동시성 처리를 위해 데이터베이스나 컬렉션을 물리적으로 분리할 필요는 없다
컬렉션
- 몽고DB에 관한 매뉴얼이나 많은 관련 글들에서는 몽고DB의 제한적인 형태의 조인 때문에 컬렉션에 가능하면 많은 데이터를 내장(embedding)할 것을 권장한다
- 이는 모델링적인 측면에선느 맞는 이야기일지 모르지만 성능적인 측면에서는 그렇지 않을 수도 있다
- (항상 같이 필요한 데이터 묶음이라면 괜찮지만 그렇지 않다면 불필요한 디스크 읽기 작업, 네트워크 비용이 발생)
- 몽고DB는 내부적으로 이미 샤딩 기능을 가지고 있기 때문에 컬렉션 단위의 샤딩은 별도로 크게 고려하지 않아도 된다 (WiredTiger, RocksDB 사용할 경우)
- 이미 몽고DB 3.0부터 도입된 WiredTiger 스토리지 엔진에서는 도큐먼트 단위의 잠금을 지원하기 때문에 하나의 컬렉션에 많은 도큐먼트가 저장된다고 해서 동시 처리 성능 저하가 발생하지 않는다
- 또한 몽고DB에서 컬렉션 단위의 샤딩을 지원하므로 컬렉션을 잘게 쪼개서 얻을 수 있는 이점 또한 제한적이다
- 컬렉션 설계에서 무엇보다 중요한 것은 샤드 키의 선정이다. 샤드 키를 잘못 선정하면 몽고DB의 데이터 분산 효과를 무효로 만들어 버릴 정도로 많은 영향을 미친다
도큐먼트
- 일반적으로 몽고DB에 저장되는 도큐먼트는 RDBMS의 레코드보다 용량이 큰 경향이 있다. 몽고DB의 BSON 도큐먼트는 최대 16MB 까지의 데이터만 저장할 수 있다. 그래서 모든 도큐먼트 하나에 모든 관련 데이터를 저장하는 것은 향후 응용 프로그램의 기능을 제한시킬 수 있다
- 도큐먼트 내에서 변경이 자주 발생하는 필드를 별도의 컬렉션으로 분리하는 것은 안정적인 서비스를 위해 고려해 볼만하다. 왜냐하면 특정 필드 하나만 변경하더라도, 실제로는 도큐먼트를 통째로 변경하는 작업이 일어나서 굉장히 비효율적인 디스크 쓰기 작업이 발생하고, 이러한 부하가 엄청나게 커지면 그동안 다른 읽기 쿼리를 실행하지 못하게 된다
- 반면에 몽고DB에서 하나의 도큐먼트 처리에 대해서만 원자적인 오퍼레이션을 보장한다는 점을 생각하면 도큐먼트를 묶어서 저장하는게 낫다고 할 수 있다
모델링 고려사항
모델링 디자인 패턴
- https://www.mongodb.com/blog/post/building-with-patterns-a-summary