MongoDB와 NoSQL

MongoDB는 크로스 플랫폼 문서 지향(Document-Oriented) 데이터베이스 시스템이다. NoSQL 데이터베이스로 분류되며, JSON과 유사한 동적 스키마 문서를 사용하여 전통적인 테이블 기반 관계형 데이터베이스 구조와는 다른 접근 방식을 취한다

NoSQL의 등장 배경과 필요성

데이터 중심 시대의 도래

현대 사회는 데이터로 가득 차 있다. SNS 게시글 작성부터 웹사이트의 클릭 한 번까지, 모든 활동이 데이터 생성, 저장, 업데이트, 이동으로 이어진다. 이러한 대량의 데이터를 효율적으로 저장하고 관리하는 방법은 서비스의 가용성, 성능, 사용자 경험에 직접적인 영향을 미친다

관계형 데이터베이스의 한계

과거에는 주로 관계형 데이터베이스(RDBMS)를 사용했다. MySQL, Oracle, PostgreSQL과 같은 시스템이 대표적이다. 이들은 테이블 형태로 데이터를 구조화하여 저장한다. Excel 스프레드시트를 떠올리면 이해하기 쉽다

ID | 이름   | 이메일            | 가입일
1  | 홍길동 | hong@hong.com    | 2025-12-05

이러한 구조는 매우 체계적이고 명확하다. 하지만 소셜 미디어의 급격한 성장으로 관리해야 할 데이터가 기하급수적으로 증가하면서 한계가 드러났다

RDBMS의 주요 한계점

  • 스키마 변경의 어려움: 정해진 구조에서 다양한 형태의 데이터를 수용하기 어렵다
  • 수평적 확장의 제약: MySQL 같은 경우 기본적으로 클러스터 구조가 기본 제공되지 않아 수평적 확장이 제한적이다
  • 복잡한 데이터 구조 표현의 한계: JSON 같은 중첩 데이터를 저장할 수는 있지만 비효율적이다

이러한 문제를 해결하기 위해 NoSQL이 등장했다

NoSQL의 특징

NoSQL(Not Only SQL)은 크게 4가지 유형으로 분류된다

Key-Value 저장소

  • Redis, DynamoDB
"userInfo" = {"name": "Hong", "age": 30, ...}

문서 지향 데이터베이스 (Document-Oriented)

  • MongoDB
{
  "_id": 1001,
  "name": "홍길동",
  "email": "hong@email.com",
  "interests": ["독서", "여행", "코딩"],
  "address": {
    "city": "서울",
    "street": "강남대로"
  }
}

컬럼 기반 데이터베이스

  • Cassandra, HBase

그래프 데이터베이스

  • Neo4j, ArangoDB

MongoDB의 핵심 철학

MongoDB는 세 가지 핵심 철학을 기반으로 설계되었다

  • 개발자 친화적: 직관적인 API와 객체 지향 프로그래밍과의 자연스러운 매핑
  • 수평적 확장 특화: 샤딩과 레플리카 셋을 통한 손쉬운 확장
  • 유연한 스키마: 스키마리스(Schemaless) 구조로 빠른 변화에 대응

BSON 데이터 포맷

MongoDB는 BSON(Binary JSON) 형식으로 데이터를 저장한다. 이는 일반 JSON보다 효율적이며 더 많은 데이터 타입을 지원한다

// 일반 JSON 형태
{
  "_id": 1001,
  "name": "홍길동",
  "createdAt": "2025-12-05T09:25:23Z"
}

// BSON 형태
{
  "_id": ObjectId("60fasfsf8fdas6f5fa44"),
  "name": "홍길동",
  "createdAt": ISODate("2025-12-05T09:25:23Z")
}

MongoDB의 기본 구조

  • Document: 개별 데이터 단위 (RDBMS의 Row에 해당)
  • Collection: Document의 집합 (RDBMS의 Table과 유사)
  • Database: Collection의 집합

MySQL VS MongoDB 비교

구조적 차이

MySQL (RDBMS)
[학생 테이블]
학번  | 이름   | 학과       | 입학년도
1001 | 홍길동 | 컴퓨터공학 | 2021
1002 | 임꺽정 | 건축학과   | 2023

[성적 테이블]
학번  | 과목코드 | 학점
1001 | CS101   | A
1001 | CS102   | B+
1002 | AR101   | A-
MongoDB (NoSQL)
{
  "_id": ObjectId("..."),
  "student_id": 1001,
  "name": "홍길동",
  "department": "컴퓨터공학",
  "enrollment_year": 2021,
  "grades": [
    {"course": "CS101", "grade": "A"},
    {"course": "CS102", "grade": "B+"}
  ]
}

주요 차이점 비교

구분RDBMSMongoDB
데이터 단위Table (테이블)Collection (컬렉션)
레코드Row (행)Document (문서)
스키마고정, 사전 정의 필수유연, 동적 변경 가능
관계 표현JOIN (외래키)Embedded Document 또는 $lookup
확장성수직적 확장 위주수평적 확장 특화

쿼리 문법 비교

데이터 삽입 (Insert) – MySQL
INSERT INTO users (id, name) VALUES (1001, '홍길동');
데이터 삽입 (Insert) – MongoDB
db.users.insertOne({
  id: 1001,
  name: "홍길동"
});
MongoDB의 스키마리스 특성
// 필드를 자유롭게 추가 가능
db.users.insertOne({
  id: 1001,
  name: "홍길동",
  nickname: "의적",  // 추가 필드
  age: 30           // 추가 필드
});
데이터 조회 (Select) – MySQL
SELECT * FROM users WHERE name = '홍길동';
데이터 조회 (Select) – MongoDB
db.users.find({name: "홍길동"});
데이터 수정 (Update) – MySQL
UPDATE users SET name = '임꺽정' WHERE id = 1001;
MongoDB
db.users.updateOne(
  {id: 1001},
  {$set: {name: "임꺽정"}}
);
조인 쿼리 (MySQL)
SELECT s.name, g.course 
FROM students AS s 
JOIN grades AS g ON s.id = g.student_id 
WHERE s.name = '홍길동';
조인 쿼리 (MongoDB [임베디드 방식 – 권장])
db.students.find(
  {name: "홍길동"},
  {name: 1, "grades.course": 1}
);
조인 쿼리 (MongoDB [$lookup 사용 – 비권장])
db.students.aggregate([
  {$match: {name: "홍길동"}},
  {$lookup: {
    from: "grades",
    localField: "student_id",
    foreignField: "student_id",
    as: "grade_info"
  }}
]);

주의: MongoDB에서 $lookup(JOIN)은 성능상 비효율적이므로 가능한 한 임베디드 문서 방식을 사용하는 것이 좋다

MongoDB vs MySQL 사용 사례

MySQL을 사용해야 하는 경우

  • 데이터 구조가 명확하고 변경이 적은 경우
  • 트랜잭션 무결성이 중요한 경우 (금융, 결제 시스템)
  • 복잡한 관계형 데이터 모델링이 필요한 경우
  • ACID 속성 보장이 필수적인 경우

MongoDB를 사용해야 하는 경우

  • 데이터 구조가 자주 변경되는 경우 (스타트업 환경)
  • 대용량 로그 데이터, 이벤트 데이터 처리
  • 빠른 프로토타이핑과 개발 속도가 중요한 경우
  • 수평적 확장이 필요한 대규모 시스템
  • JSON 형태의 비정형 데이터 저장

MongoDB의 주요 특징과 장점

문서 모델 (Document Model)

MongoDB의 가장 큰 장점은 객체 지향 프로그래밍과의 자연스러운 매핑이다

Address address = new Address("서울");

User user = new User(
    "홍길동",
    30,
    Arrays.asList("Java", "Python", "JavaScript"),
    address
);

// MongoDB에 직접 저장
collection.insertOne(user);

이는 ORM의 복잡성을 크게 줄여준다. RDBMS에서는 skills를 별도 테이블로 분리하고, Address도 따로 저장해야 하지만, MongoDB는 객체 구조 그대로 저장할 수 있다

스키마 유연성

// 첫 번째 문서
db.users.insertOne({name: "홍길동"});

// 두 번째 문서 - 필드 자유롭게 추가
db.users.insertOne({
  name: "임꺽정",
  age: 25,
  hobbies: ["독서", "운동"]
});

빠르게 변화하는 비즈니스 요구사항에 유연하게 대응할 수 있다

뛰어난 성능

인덱싱
  • 단일 필드 인덱스
  • 복합 인덱스
  • 텍스트 인덱스
  • 지리공간 인덱스
메모리 맵핑 파일 (Memory-Mapped Files)

MongoDB는 운영체제의 가상 메모리 기능을 활용하여 디스크 I/O를 효율적으로 관리한다

  • 데이터 파일을 메모리 주소 공간에 매핑
  • 자주 접근하는 데이터를 메모리에 캐싱
  • 운영체제가 자동으로 페이지 교체 관리

실무 예시: 동일한 쿼리를 반복 실행하면 두 번째부터는 캐시된 데이터를 사용하여 더 빠르게 응답한다

샤딩 (Sharding)

샤딩은 대용량 데이터를 여러 서버에서 분산 저장하는 기법이다

샤딩이 필요한 이유

단일 서버의 한계

  • 저장 용량 제한
  • 처리 성능 한계
  • 메모리 부족 문제
샤딩 구성 요소
Shard (샤드)
  • 실제 데이터를 저장하는 서버
  • 각각 ReplicaSet으로 구성
mongos (쿼리 라우터)
  • 클라이언트 요청을 적절한 샤드로 라우팅
  • 쿼리 분산 처리
Config Server (구성 서버)
  • 샤드의 메타데이터 관리
  • 어떤 데이터가 어떤 샤드에 있는지 추적
Shard Key(샤딩 키)
  • 데이터 분산의 기준이 되는 필드
  • 잘못 선택하면 데이터 불균형(핫스팟) 발생
샤딩 구조
Client
  ↓
mongos (Router) ← Config Server
  ↓
  ├─→ Shard 1 (userId: 1-1000)
  ├─→ Shard 2 (userId: 1001-2000)
  └─→ Shard 3 (userId: 2001-3000)
샤딩의 장단점
장점
  • 수평적 확장 가능
  • 대용량 데이터 처리 효율적
  • 트래픽 분산으로 부하 감소
단점
  • 샤딩 키 선택이 중요 (잘못 선택 시 핫스팟 발생)
  • 시스템 복잡도 증가
  • 운영 및 관리 비용 증가

레플리카 셋 (Replica Set)

레플리카 셋은 데이터의 고가용성과 장애 복구를 위한 복제 매커니즘이다

레플리카 셋 구성
Primary Node (주 노드)
  • 모든 쓰기 요청 처리
  • 읽기 요청도 기본적으로 처리
  • 데이터의 원본
Secondary Node (보조 노드)
  • Primary의 데이터를 실시간 복제
  • Primary 장애 시 자동으로 승격
  • 읽기 요청 분산 처리 가능 (설정에 따라)
Arbiter Node (중재자 노드)
  • 데이터를 저장하지 않음
  • Primary 선출 투표에만 참여
  • 홀수 구성을 위해 사용
구성 규칙
  • 최소 3대 이상의 홀수 노드로 구성
  • 일반적으로 Primary 1대 Secondary 2대 구성
자동 장애 복구 (Automatic Failover)
정상 상태
Primary ← Secondary 1
        ← Secondary 2

Primary 장애 발생
X Primary   Secondary 1 → 새로운 Primary로 승격
            Secondary 2
레플리카 셋의 장단점
장점
  • 고가용성 보장 (무중단 서비스)
  • 자동 장애 복구
  • 읽기 부하 분산 가능
  • 데이터 백업 효과
단점
  • 서버 수만큼 스토리지 비용 증가
  • 복제 지연(Replication Log) 발생 가능
  • Primary와 Secondary 간 일시적 데이터 불일치 가능

출처 – 가장 쉽고 깊게 알려주는 MongoDB 완벽 가이드 [ By. 비전공자 & Kakao 개발자 ]