장점
- 비동기 드라이버를 사용할 수 있다.
- 현재 JDBC의 경우 동기 드라이버만 존재해 블러킹 포인트가 된다.
- RDB와 개념이 유사해, 쿼리 변환기가 있을 만큼 개념적으로 어색하지 않다.
- 사용법도 마찬가지로 이질감이 없다.
- RDB에 비해 성능이 100배 이상 빠르다.
- 별도의 캐시 솔루션이 필요하지 않을 만큼 성능 문제에서 우월하다.
- 스키마 관리가 필요 없다.
- 이미 성숙기에 접어들어 운용, 개발, 유틸리티에 부족함이 없다.
- Cassandra, Couchbase, MongoDB의 경우 대규모 트래픽, 데이터 저장, fail-over, fault-tolerance에 다양한 대안이 마련 되어있는 상황이다.
- redis과 비교해봐도 충분히 안정권에 들어온 상태다.
- 샤드 추가가 간편하다.
- 다른 NOSQL처럼 리밸런싱은 불가능하지만, 그럼에도 적정 수치때 샤드를 추가해준다면 장점은 충분히 누릴 수 있다.
단점
- 복잡한 쿼리를 사용할 수 없다.
- join을 사용할 수 없다.
- 메모리 사용량이 큰 편이다.
- 메모리 부족 시 퍼포먼스가 급락한다.
- 데이터 일관성이 보장되지 않는다.
- 다만, ACID 도입 베타 릴리즈 진행 중이다.
적절한 사용 사례
- 로그성 데이터나 빅데이터 처리의 중간 저장소
- RDB보다는 성능이 우월하고, 파일보다는 다양한 유틸리티성 기능과 검색에 유연하다.
- 설정 데이터의 보관소
- 이는 Redis같은 Key-Value DB가 유용하다고 여겨질 수 있으나, 검색 조건의 다양화가 필요할 경우 MongoDB가 훨씬 유용하다.
- null 필드가 많이 존재할 때
- 데이터에 null 필드가 가변으로 다양하게 존재할 경우, rdb보다 스토리지 사용량, 처리 속도등에서 효율이 좋다.
- 압도적인 퍼포먼스가 필요할 떄
- RDB 대비 100배 이상의 차이를 내는 압도적인 퍼포먼스 차이.
- memory mapped file 기반 구조에서의 장점
- nosql 계열에서 압도적인 index 활용도
- Single Field Indexes : 기본적인 인덱스 타입
- Compound Indexes : RDBMS의 복합인덱스 같은 거
- Multikey Indexes : Array에 매칭되는 값이 하나라도 있으면 인덱스에 추가하는 멀티키 인덱스
- Geospatial Indexes and Queries : 위치기반 인덱스와 쿼리
- Text Indexes : String에도 인덱싱이 가능
- Hashed Index : Btree 인덱스가 아닌 Hash 타입의 인덱스도 사용 가능
- 집계 연산, paging, 복잡한 쿼리 (단일 document 한정)가 필요할 때
- key-value db (redis, aerospike 등)와 달리 집계 연산, paging이 가능함.
- RDB와 동일한 접근의 데이터 스토어로서 사용 가능함.
- 실제로 쿼리 변환기가 존재함.
- RDB와 동일한 접근의 데이터 스토어로서 사용 가능함.
- key-value db (redis, aerospike 등)와 달리 집계 연산, paging이 가능함.
- 스키마 관리가 불필요함.
- json 기반 저장 구조로, 유연한 동적 데이터 저장이 가능.
- 정규화할 데이터보다는, 단일 스키마 기반의 참조 데이터 저장에 장점이 많음.
- 로그성 데이터도 매우 적합 함.
부적절한 사용 사례
- 데이터 무결성이 가장 중요한 가치 일 때
- 단일 document 무결성은 유지되지만, 멀티 document 무결성은 유지 되지 않음.
- 애초에 join이 되지 않는지라, 일말이 오차는 존재할 수 있음.
- 단일 document 무결성은 유지되지만, 멀티 document 무결성은 유지 되지 않음.
- 데이터 처리량보다 일관성 있는 데이터 구조가 중요할 때
- 데이터 처리량이 빠른 이유는 ACID를 수행하지 않기 때문이다.
- 특히 샤딩+레플리카를 조합해서 사용 할 때 무결성이 깨진 상태의 데이터가 조회 될 수 있다. (document 자체가 corrupt 된다는 의미는 아니고, 조회한 시점 이전의 데이터가 조회 될 수 있거나, 이미 삭제된 데이터가 조회될 수 있다는 의미)
- 운용 이슈에 대한 우려 사항들이 해소가 덜 됐을 때
- NoSQL 계열도 여타 DB와 마찬가지로 운용 이슈가 중요하고, 이에 대한 경험과 노하우가 부족하다면, 이 부분이 리스크가 될 수 있다.
- 임계치가 높을 뿐 RDB와 마찬가지로 데이터가 많아지면 성능이 저하되는 부분은 마찬가지고, 이를 해결하기 위한 방안과, 풀 스캔이나, 메모리 사용량이 커질 수 있는 작업을 production 레벨에선 사용할 수 없게 만들어야 한다.
- 데이터 무결성이 무엇보다 중요할 때
- 결제, 아이템 등을 담기엔 여전히 RDB보단 불안한 면이 존재한다.
- 엄격한 데이터 타입 검사나 연관 관계가 중요할 때
- 데이터 타입이 동적 결정되는 스키마리스 DB이고, 컬럼도 동적 컬럼이다보니 마이그레이션이 어려운 편이고, 제약 검사를 추가할 만큼 스키마가 중요하다면 선택해선 안된다.
- 코드 레벨에서 제어할 방법도 있지만, 접근 권한을 준 다른 서버 혹은 툴 등에서 쿼리를 날렸을 때 이를 막을 수 없다.
- 또한 테이블 간 연관 관계가 중요하다면, 이 또한 선택지에서 배제해야 한다.
- 위에서 언급한 대로 여러 document (테이블)을 동시에 조회할 수 없기에, 동일한 시점에 무결성이 깨지지 않은 데이터를 조회할 수 없다.
- 데이터 타입이 동적 결정되는 스키마리스 DB이고, 컬럼도 동적 컬럼이다보니 마이그레이션이 어려운 편이고, 제약 검사를 추가할 만큼 스키마가 중요하다면 선택해선 안된다.
참고 자료
- https://www.MongoDB.com/compare/MongoDB-mysql
- http://blog.kjslab.com/159
- http://givemesource.tistory.com/87