MongoDB / 소개, 주요 특징, 사용 사례, 도입 시 고려해야 할 점
MongoDB는 데이터를 행과 열 중심의 테이블 대신 문서(document) 단위로 저장하는 데이터베이스입니다. 상품별 속성이 다른 카탈로그나 중첩된 사용자 정보처럼 함께 읽는 데이터를 한 묶음으로 다루는 작업에서 검토할 수 있지만, 유연한 구조가 설계나 성능 검증을 대신하지는 않습니다.
이 글은 MongoDB의 저장 방식, 주요 기능, 사용 사례와 도입 판단 기준을 설명합니다. 데이터베이스 계열 전체의 차이는 NoSQL 데이터 모델과 관계형 데이터베이스 비교에서 확인할 수 있습니다.
MongoDB는 데이터를 어떻게 저장하나요?
문서는 필드 이름과 값의 쌍으로 구성된 데이터 단위이며, 문서를 모아 두는 논리적 공간을 컬렉션(collection)이라고 합니다. 하나의 데이터베이스 안에 상품, 주문, 고객처럼 목적이 다른 컬렉션을 둘 수 있습니다.
MongoDB는 BSON(Binary JSON) 형식으로 문서를 저장합니다. BSON은 JSON(JavaScript Object Notation)의 구조를 바이너리로 표현하면서 날짜, ObjectId 같은 추가 자료형을 지원합니다. 따라서 JSON 텍스트 파일을 그대로 보관하는 저장소로 이해하면 정확하지 않습니다. MongoDB 문서 구조 안내에서 자료형과 식별자 규칙을 확인할 수 있습니다.
다음은 문서의 모양을 이해하기 위한 가상의 상품 JSON입니다. 일반 컬렉션의 _id는 문서를 식별하는 필드입니다. 이 예제에서는 이해하기 쉬운 문자열을 사용했으며, 실제 애플리케이션에서는 식별자 형식과 중복 처리 규칙을 정해야 합니다.
{
"_id": "book-101",
"name": "데이터베이스 입문",
"category": "books",
"price_krw": 24000,
"attributes": {
"author": "김민아",
"pages": 320
},
"tags": [
"database",
"beginner"
]
}
attributes는 중첩 객체이고 tags는 배열입니다. 책에는 저자와 쪽수를, 전자 제품에는 배터리 정보를 두는 식으로 항목별 속성을 표현할 수 있습니다. 다만 가격의 자료형, 필수 필드와 누락 값 처리 등 공통 규칙은 유지해야 합니다.
MongoDB의 주요 기능과 적용 조건
유연한 스키마와 검증
스키마(schema)는 필드, 자료형과 필수 조건처럼 데이터의 구조를 정의한 규칙입니다. MongoDB는 기본적으로 같은 컬렉션의 문서가 모두 동일한 필드를 가질 필요가 없습니다. 그러나 “스키마를 생각하지 않아도 된다”는 뜻은 아닙니다.
스키마 검증으로 허용 자료형과 값 범위를 제한할 수 있습니다. 가격에 숫자와 문자열이 섞이거나 날짜가 서로 다른 형식으로 저장되는 문제를 막으려면 애플리케이션의 검사와 데이터베이스 검증을 함께 설계합니다. 기존 데이터에 규칙을 추가할 때는 어떤 문서가 규칙을 어기는지와 갱신 시 처리 방식을 먼저 확인해야 합니다.
조건 조회, 집계와 관계 조회
MongoDB의 조회는 필드 조건과 연산자를 사용합니다. SQL 문장을 그대로 실행하는 방식과는 다르므로 사용하는 프로그래밍 언어의 드라이버나 셸에서 지원하는 문법을 익혀야 합니다. 중첩 필드는 점 표기법으로 접근할 수 있고 배열 조건도 표현할 수 있습니다.
집계 파이프라인(aggregation pipeline)은 필터링, 그룹화와 계산 등의 단계를 연결해 데이터를 가공하는 기능입니다. 예를 들어 주문에서 취소되지 않은 항목을 고른 뒤 상품별 수량을 합산할 수 있습니다. 집계 파이프라인 공식 안내에 단계별 동작이 설명되어 있습니다.
$lookup은 다른 컬렉션의 문서를 연결하는 왼쪽 외부 조인 기능을 제공합니다. 따라서 “MongoDB에는 조인이 없다”는 설명은 맞지 않습니다. 다만 $lookup의 지원 범위와 성능 조건을 확인해야 하며, 관계형 데이터베이스의 외래 키 제약처럼 참조 무결성이 자동으로 관리된다고 가정하면 안 됩니다.
인덱스와 성능
인덱스(index)는 조건에 맞는 문서를 찾을 때 읽어야 하는 데이터를 줄이는 자료 구조입니다. 단일 필드나 여러 필드를 묶은 복합 인덱스 등을 조회 요구에 맞춰 사용할 수 있습니다. 인덱스 공식 문서는 조회 이점과 쓰기 비용을 함께 설명합니다.
인덱스가 늘면 저장 공간과 쓰기 갱신 비용도 늘어납니다. 실제 성능은 문서 크기, 인덱스, 읽기·쓰기 비율, 메모리와 디스크, 네트워크에 따라 달라집니다. “NoSQL이라서 빠르다”는 결론 대신 대표 조회를 실행 계획과 실제 부하로 평가해야 합니다.
트랜잭션과 읽기·쓰기 보장
MongoDB의 단일 문서 갱신은 원자적입니다. 즉, 하나의 갱신 작업을 부분적으로만 적용하지 않습니다. 여러 문서의 변경을 함께 성공하거나 실패하게 해야 할 때는 복제 세트나 샤딩 클러스터에서 지원하는 여러 문서 트랜잭션을 검토합니다. 단독 서버 구성에서는 같은 기능을 사용할 수 있다고 가정하지 않습니다.
ACID는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)을 뜻합니다. MongoDB 트랜잭션 문서에 따라 배포 구성과 설정 조건을 확인해야 합니다. 주문 생성과 재고 차감을 별도 문서에 저장한다면 트랜잭션 범위, 동시 요청과 실패 시 재시도를 설계할 필요가 있습니다.
읽기에서 어떤 데이터 상태를 허용할지 정하는 read concern과 쓰기 성공을 어느 수준까지 확인할지 정하는 write concern도 별개의 설정입니다. 사용자에게 결제가 완료되었다고 알리기 전에 필요한 보장과, 복제본에서 오래된 값을 읽어도 되는 작업을 구분해야 합니다.
임베딩과 참조 중 무엇을 선택하나요?
임베딩(embedding)은 관련 데이터를 한 문서 안에 넣는 방식이고, 참조(reference)는 다른 문서의 식별자로 연결하는 방식입니다. 공식 데이터 모델링 안내는 함께 접근하는 데이터를 함께 저장하는 원칙을 제시하며, 임베딩과 참조 선택 안내는 관계와 갱신 방식에 따른 차이를 설명합니다.
| 판단 기준 | 임베딩을 검토할 상황 | 참조를 검토할 상황 |
|---|---|---|
| 읽는 방식 | 상위 항목과 관련 정보를 대부분 함께 읽음 | 관련 정보를 독립적으로 조회함 |
| 변경 방식 | 한 문서에서 함께 갱신할 내용 | 여러 문서가 공유하며 자주 바뀌는 정보 |
| 데이터 크기 | 크기와 개수가 제한된 묶음 | 계속 증가하거나 큰 별도 항목 |
| 예시 | 주문의 배송 주소와 구매 당시 상품명 | 전체 리뷰, 공유 고객 프로필 |
주문에 구매 당시 배송 주소를 복사하면 주문 기록의 의미를 보존할 수 있습니다. 반면 고객의 현재 연락처를 모든 주문에 복사해 두면 변경 시 여러 복사본을 관리해야 합니다. “과거의 사실”인지 “항상 최신이어야 하는 값”인지 먼저 구분하는 것이 중요합니다.
일반 BSON 문서는 최대 16 MiB입니다. 모든 댓글이나 로그를 하나의 배열에 계속 추가하면 크기 제한과 갱신 부담에 부딪힐 수 있습니다. 문서 크기 제한을 고려해 별도 컬렉션, 참조 또는 크기를 제한한 묶음으로 설계합니다.
어떤 사용 사례에 적합한가요?
아래는 문서 모델을 검토할 만한 상황이지 업종별 도입을 보장하는 목록은 아닙니다. 실제 조회와 변경이 어떻게 이루어지는지가 선택의 기준입니다.
| 사용 사례 | 문서 모델을 검토하는 이유 | 함께 확인할 조건 |
|---|---|---|
| 상품 카탈로그 | 종류별 속성 차이와 중첩 정보 | 공통 필드 검증, 필터와 정렬용 인덱스 |
| 사용자 프로필·콘텐츠 | 한 화면에서 관련 속성을 묶어 읽음 | 개인정보 접근 권한, 큰 배열과 중복 데이터 |
| 이벤트·장치 기록 | 발생 시점별 구조와 부가 속성을 저장 | 보관 기간, 장치·시간 범위 조회, 용량 증가 |
| 주문 데이터 | 주문 당시 상태를 한 묶음으로 보관 | 재고·결제와의 정합성, 동시 갱신과 트랜잭션 |
다양한 테이블을 조합하는 보고서, 공통 관계와 제약 조건, 복잡한 다대다 갱신이 핵심이라면 관계형 데이터베이스도 함께 비교해야 합니다. JSON을 저장한다는 이유만으로 기존 데이터베이스를 바꿀 필요는 없습니다. 문서 모델로 바꿨을 때 주요 조회와 운영 부담이 실제로 개선되는지 확인합니다.
상품을 넣고 조회하는 간단한 예제
다음 명령은 MongoDB Shell인 mongosh에서 실행하는 예입니다. 먼저 별도의 실습용 MongoDB 배포에 연결하고, 해당 데이터베이스에 읽기·쓰기와 인덱스 생성 권한이 있는 계정 및 설치된 mongosh를 준비합니다. 연결 방법은 MongoDB Shell 문서에서 확인할 수 있습니다.
예제는 mongodb_intro_demo 데이터베이스의 product_catalog 컬렉션에 상품을 하나 넣습니다. 첫 실행에는 이 이름의 컬렉션이 비어 있는 실습 환경을 사용하세요. 운영 데이터베이스가 아닌지 연결 대상을 확인한 뒤 실행합니다.
db = db.getSiblingDB("mongodb_intro_demo");
db.product_catalog.insertMany([
{
"_id": "book-101",
"name": "데이터베이스 입문",
"category": "books",
"price_krw": 24000,
"attributes": {
"author": "김민아",
"pages": 320
},
"tags": [
"database",
"beginner"
]
}
]);
insertMany()는 문서를 삽입합니다. 같은 _id를 다시 넣으면 일반 컬렉션에서 중복 키 오류가 발생하므로, 반복 실습은 새 실습 데이터베이스에서 하거나 자신이 추가한 예제 문서만 명확히 식별해 처리합니다. 오류가 났다고 기존 컬렉션 전체를 삭제하지 않습니다.
다음은 books 분류에서 30,000원 미만인 상품을 찾아 식별자·이름·가격만 가져오고 가격 오름차순으로 정렬하는 조회입니다. 예제 데이터만 있다면 book-101이 조건에 맞습니다.
db.product_catalog.find(
{ category: "books", price_krw: { $lt: 30000 } },
{ _id: 1, name: 1, price_krw: 1 }
).sort({ price_krw: 1 });
$lt는 “보다 작음”, 조회의 두 번째 객체는 반환할 필드를 지정하는 프로젝션(projection)을 뜻합니다. sort()의 1은 오름차순입니다. find() 공식 문서에서 조건과 프로젝션을 확인할 수 있습니다.
분류별로 가격 조건과 정렬을 자주 쓰는 경우 다음 복합 인덱스를 후보로 검토할 수 있습니다. 실제 운영에서는 데이터 분포와 다른 조회까지 고려해 createIndex()를 실행합니다.
db.product_catalog.createIndex(
{ category: 1, price_krw: 1 }
);
다음 명령은 문서를 바꾸지 않고 조회를 실행해 실행 통계를 보여 줍니다. explain("executionStats") 결과에서 선택된 실행 계획, 읽은 키와 문서 수, 반환한 문서 수를 확인합니다. 작은 데이터에서는 전체 스캔이 선택될 수도 있으며, 인덱스를 만들었다는 사실만으로 더 빨라졌다고 판단하면 안 됩니다.
db.product_catalog.find(
{ category: "books", price_krw: { $lt: 30000 } }
).sort({ price_krw: 1 }).explain("executionStats");
복제와 샤딩은 서로 다른 기능입니다
복제 세트(replica set)는 같은 데이터를 유지하는 서버 묶음입니다. 일반적으로 주 서버(primary)가 쓰기를 받고 보조 서버(secondary)가 변경을 복제하며, 장애가 나면 조건을 충족하는 구성원이 새 주 서버를 선출할 수 있습니다. MongoDB 복제 문서에서 선출과 비동기 복제의 조건을 확인하세요.
장애 전환 중에는 일시적인 쓰기 지연이나 오류가 발생할 수 있고, 보조 서버 읽기에는 복제 지연이 반영될 수 있습니다. 복제를 무중단이나 데이터 손실 방지의 무조건적인 보장으로 표현하면 안 됩니다. 재시도와 중복 요청 처리, 필요한 읽기·쓰기 보장을 애플리케이션과 함께 설계해야 합니다.
샤딩(sharding)은 데이터를 여러 서버에 나누어 저장하는 수평 확장 방식입니다. 샤드 키는 문서를 분산하고 조회를 전달하는 데 쓰는 필드입니다. 한쪽 키에 요청이 몰리거나 샤드 키 없는 조회가 모든 샤드를 방문하면 확장 효과가 제한됩니다. 샤딩 공식 문서가 키 선택과 운영 복잡성을 설명합니다.
복제와 샤딩은 역할이 다르며 함께 사용할 수도 있습니다. 데이터가 커질 가능성만으로 처음부터 샤딩을 적용하기보다 문서 설계, 인덱스와 현재 병목을 확인하고 복잡성과 비용을 감당할 이유가 있을 때 검토합니다.
도입 전에 무엇을 확인해야 하나요?
- 핵심 작업을 정합니다. 상품 상세, 분류별 가격 검색, 주문 저장처럼 필터·정렬·갱신 단위를 적고 관계형 모델과 문서 모델에서 각각 구현해 봅니다.
- 모델과 정확성을 검토합니다. 임베딩·참조, 문서 크기, 필드 검증, 인덱스, 트랜잭션과 저장 직후 읽기 요구를 정합니다.
- 대표 부하로 비교합니다. 실제에 가까운 데이터와 요청 분포로 지연, 처리량과 오류를 측정합니다. 제품 버전, 하드웨어와 설정을 기록하고 장애·복구 시나리오도 확인합니다.
- 운영 방식을 선택합니다. 직접 운영할지 관리형 서비스를 사용할지 판단하고, 백업·복구, 모니터링, 업그레이드와 지원 책임을 나눕니다.
- 이전과 되돌리기를 준비합니다. 식별자·자료형 변환, 누락 검증, 전환 중 쓰기 처리와 기존 저장소로 돌아갈 조건을 정합니다.
MongoDB Atlas는 관리형 클라우드 서비스이고, 직접 운영하는 MongoDB 배포와 운영 책임이 다릅니다. Atlas 공식 문서에서 필요한 기능과 배포 옵션을 확인하고, 인스턴스 외에 저장소·백업·네트워크 및 운영 인력까지 비용에 포함합니다.
실서비스에서는 최소 권한 계정, 암호화된 연결, 네트워크 접근 제한과 자격 증명 관리를 검토해야 합니다. MongoDB 보안 안내를 배포 방식에 맞춰 적용하세요. 복제본에도 실수로 지운 데이터가 전파될 수 있으므로 복제가 백업을 대신하지 않습니다. 백업 방식 안내에 따라 백업을 준비하고 실제 복원 가능 여부까지 확인합니다.




