MongoDB란?
MongoDB는 NoSQL 데이터베이스 중 하나로, 데이터가 JSON 형태의 문서(Document)로 저장되는 문서 지향(Document-Oriented) 데이터베이스이다.
NoSQL 데이터베이스란?
NoSQL은 "Not Only SQL"의 약자로, 관계형 데이터베이스와 달리 고정된 스키마를 요구하지 않는 데이터베이스 기술을 말한다.
- 스키마리스(Schema-less) : 데이터 구조를 사전에 정의하지 않아도 된다.
- 유연성(Flexibility) : 데이터 모델링이 자유롭고, 다양한 형태의 데이터를 저장할 수 있다.
- 확장성(Scalability) : 수평적 확장이 용이하며, 대규모 데이터 처리에 적합하다.
- 빠른 성능(High Performance) : 특정 사용 사례에 맞게 최적화되어 읽기/쓰기 속도가 빠르다.
MongoDB의 주요 특징
- 문서 기반 데이터 모델 : 데이터는 BSON(Binary JSON) 포맷으로 저장되며, JSON 형태의 키-값 쌍으로 구성된다.
- 수평적 확장(Sharding) : 데이터를 여러 서버에 분산 저장하여 대량의 데이터를 처리할 수 있다. 높은 확장성과 가용성을 제공한다.
- 복제(Replication) : MongoDB는 데이터 복제를 통해 데이터의 가용성과 안정성을 높인다. 복제본(replica set)을 활용하여 장애 복구 기능을 제공한다.
- 강력한 쿼리 언어 : MongoDB는 필터링, 정렬, 집계 등을 지원하는 강력한 쿼리 언어를 제공한다. Aggregation pipeline을 사용하면 복잡한 데이터 분석도 쉽게 처리 가능하다.
MongoDB의 장점과 단점
JSON 기반의 문서 지향 데이터 모델로써 사람이 읽기 쉽고 직관적인 데이터 형식을 사용하며, 애플리케이션 개발 시 데이터 구조와 잘맞다. 또한 데이터의 구조를 사전에 정의하지 않아도 되므로, 데이터 변경이 잦은 환경에서 유리하다. 그리고 Sharding을 통해 데이터를 여러 노드에 분산 저장할 수 있어, 대규모 데이터 처리에 적합하기도 하며 특히 복제본을 통해 데이터 안정성을 보장이 가능하고 장애 발생시 빠르게 복구가능하다는 장점이 있다.
하지만 기본적으로 데이터 일관성이 필요할 경우에는 추가적인 설정이 필요하며 쿼리성능 또한 관계형 데이터베이스에서 지원한 복잡한 JOIN 연산이 없기 때문에 대신하기 위한 데이터 모델링이 필요할 수 있다. 그리고 MongoDB는 데이터를 인덱싱하고 캐싱하는 데 많은 메모리가 필요할 수 있고 관계형 데이터베이스에 익숙한 개발자들에게는 초기 학습 곡선이 높을 수 있다.
샤딩은 데이터를 여러 서버에 분산 저장하는 기술이다. 하나의 DB가 감당하기 어려울 만큼 데이터가 커지거나 트래픽이 증가하면 데이터를 여러 조각(shard)으로 나누어 서로 다른 서버에 저장하여 확장성과 성능을 높일 수 있다.
샤딩(Shrding)의 핵심 개념
Shard : 데이터 조각이다. 각 샤드는 데이터의 일부를 저장하며, 독립적인 데이터베이스 역할을 한다.
Shard Key : 데이터를 분할하는 기준이 되는 키이다. 이 키를 기반으로 각 데이터가 어느 샤드에 저장될지 결정한다.
Config Sergver : 샤드 메타데이터를 관리하는 서버이다. 어떤 데이터가 어떤 샤드에 있는지 기록한다.
Query Router (Mongos) : 클라이언트의 요청을 적절한 샤드로 라우팅하는 역할을 한다.
샤딩의 동작 방식
1. 데이터를 삽입하거나 조회할 때, Shard Key를 사용해 해당 데이터가 저장될 샤드를 결정한다.
2. 클라이언트는 Mongos를 통해 데이터베이스에 접근, Mongos가 적절한 샤드로 요청을 전달한다.
3. 데이터를 분산 저장하므로 단일 서버의 용량 한계를 극복할 수 있고, 일기 및 쓰기 작업을 병렬로 처리하여 성능을 향상 시킨다.
샤딩의 장점
- 수평적 확장 : 데이터베이스 용량을 늘리기 위해 더 많은 서버를 추가할 수 있다.
- 성능 향상 : 읽기 및 쓰기 작업이 여러 서버로 분산되므로 병목현상을 줄일 수 있다.
- 가용성 증가: 특정 샤드에 장애가 발생해도 다른 샤드가 정상적으로 동작한다.
샤딩의 단점
- 설정 및 관리가 복잡하며, 올바른 Shard Key 선택이 매우 중요하다.
- 잘못된 샤드 키로 인해 데이터가 불균형하게 분산될 수 있다.
- 복잡한 쿼리는 성능 저하를 초래할 수 있다.
MongoDB는 내장된 샤딩 기능을 통해 이러한 과정을 자동으로 철해주며, 대규모 데이터베이스 운영을 손쉽게 관리할 수 있도록 해준다.
Document, Collection, Database
Document
- MongoDB에서 데이터의 기본 저장 단위이다.
- JSON과 유사한 형태를 가지며, 각 Document는 고유한 데이터를 저장한다.
- 한 Document는 키-값 쌍으로 이루어져 있으며, 숫자, 문자열, 배열, 객체 등 다양한 데이터 타입을 사용할 수 있다.
{
"_id": "12345",
"name": "Alice",
"age": 28,
"skills": ["Python", "MongoDB", "JavaScript"]
}
- _id는 각 Document를 고유하게 식별하기 위해 자동 생성하는 필드이다.
Collection
Document의 집합으로, 관계형 데이터베이스의 테이블에 해당한다.
하나의 Collection 안에는 여러 Documnet가 포함되며, 서로 다른 구조를 가진 Document도 저장할 수 있다.
users 라는 Collection에 아래 두 Document를 저장할 수 있다.
{ "_id": 1, "name": "Alice", "age": 28 }
{ "_id": 2, "name": "Bob", "city": "New York" }
일반적으로는 Collection은 동일한 유형의 데이터를 그룹화하는 데 사용된다.
한 Document에 "age", "city"가 저장될 수 있는 이유는 MongoDB가 스키마리스(Schema-less) 데이터베이스이기 때문에다 고유한 구조를 가질 수 있지만 다른 Document와 반드시 동일한 필드를 가질 필요가 없다.
두 필드가 공존할 경우 동일한 필드를 추가해 저장할 수 있는 유연성도 제공한다.
{ "_id": 3, "name": "Charlie", "age": 30, "city": "San Francisco" }
하지만 과도하게 서로 다른 구조의 Document를 저장하면 데이터 관리가 어렵고, 쿼리 및 성능 최적화가 복잡해질 수 있다. 따라서 적절으 스키마를 암묵적으로 설계하는 것이 좋다.
Databese
- 여러 Collection을 포함하는 상위 계층이다.
- MongoDB 인스턴스는 여러 Database를 관리할 수 있으며, 각 Database는 고유한 이름을 가진다
- Databases 내부에서 Collection 간에는 독립적으로 데이터가 저장된다.
따라서 정리하면 이렇게 볼 수 있다.
- Database : 하나의 도서관
- Collection : 도서관의 특정 책장 (소설 섹션, 과학 섹션 등)
- Document : 책장에 있는 책 한권 (각 책은 다른 내용과 구조를 가질 수 있음)
구조와 독립성
각 Database는 별개의 네임스페이스를 가지므로, 서로 다른 Database에 동일한 Collection 이름과 동일한 Document가 존재해도 충돌하지 않는다.
DatabaseA와 DatabaseB라는 두 개의 Database가 있다.
두 Database에 모두 users라는 이름의 Collection이 있다고 가정한다.
users Collection 내부에 동일한 Document가 존재해도 문제가 없다.
- DatabaseA.users: { "_id": 1, "name": "Alice", "age": 28 }
- DatabaseB.users: { "_id": 1, "name": "Alice", "age": 28 }
각 Collection 내부에서만 _id 필드가 고유하면 전혀 충돌이 발생하지 않는다.
하지만 과도하게 사용한다면 데이터 관리와 동기화 작업이 복잡해지고, 데이터 중복으로 인해 저장 공간이 낭비 될 수 있으므로 요구사항에 맞게 적절히 사용하자.
BSON과 JSON 차이
- JSON (JavaScript Object Notation) : 사람이 읽기 쉽고, 데이터 교환에 널리 사용되는 텍스트 기반 데이터 형식이다.
- BSON (Binary JSON) : MongoDB가 내부적으로 사용하는 이진 포맷으로, JSON보다 빠른 읽기/쓰기 성능을 제공한다. BSON은 추가적인 데이터 타입을 지원한다.
CRUD : Create, Read, Update, Delete
- Create : 데이터를 삽입(insertOne, insertMany)
- Read : 데이터를 조회(find, findOne)
- Update : 데이터를 수정(updateOnde, updateMany)
- Delete : 데이터를 삭제(deleteOne, deleteMany)
Index, Aggregation Pipeline, Replica Set
- Index : 데이터를 빠르게 검색할 수 있도록 돕는 구조이다. 적절한 Index를 설계하면 조회 성능이 향상된다.
- Aggregation Pipeline : 데이터를 집계하고 변환하기 위한 도구로, 여러 단계의 연산을 체인 형태로 연결하여 복잡한 데이터 분석 작업을 수행할 수 있다.
- Replica Set : 동일한 데이터를 여러 서버에 복제하여 고가용성과 데이터 안정성을 보장하는 기능이다.