MySQL에 익숙한 내가 MongoDB를 만나다.

대호 Dorant·2025년 6월 21일
7


안녕하세요? 오랜만이네요.

저는 RDB(특히, MySQL)를 주력(?)으로 사용해오던 개발자입니다.

최근에 MongoDB를 접할 일이 생겨, 어쩔 수 없이(?) MongoDB를 공부하게 되었어요. 처음에는 "NoSQL이 뭐가 그리 다르겠어?" 싶었는데, 막상 써보니 생각보다 많은 것들이 달라서 당황했습니다.

특히 MySQL의 JOIN과 GROUP BY에 익숙했던 저에게 Aggregation Pipeline은 정말 새로운 세계였어요. MongoDB Compass라는 도구도 처음 써보고, 정규표현식을 이렇게 활용할 수 있다는 것도 신기했고요.

그래서 저와 비슷한 상황에 있는 분들께 도움이 될까 싶어, 제가 MongoDB를 배우면서 겪은 시행착오와 "아, 이래서 MongoDB를 쓰는구나!" 싶었던 순간들을 정리해서 공유해보려고 합니다.

이 글에서 다음과 같은 것들을 얻어가실 수 있으면 좋겠습니다.

💡 MySQL 사고방식에서 MongoDB로 전환하는 핵심 포인트
💡 MongoDB Compass를 활용한 실무 데이터 조회법
💡 Aggregation Pipeline의 실전 적용 사례
💡 데이터 모델링 접근법의 차이점

시작해보겠습니다.

MongoDB를 선택해야 하는 실무적 이유

1. 스키마 유연성이 가져다주는 개발 속도

MySQL에서는 기획 변경 때마다 스키마 변경 작업이 필요했습니다.

// 새로운 요구사항마다 스키마 수정
ALTER TABLE posts ADD COLUMN view_count INT DEFAULT 0;
ALTER TABLE posts ADD COLUMN tags JSON;
// 배포 대기, 롤백 계획, 다운타임 고려...

하지만..! nosql인 MongoDB에서는 즉시 필드를 추가할 수 있습니다.

// 언제든 자유롭게 필드 추가
{
  "title": "게시글",
  "content": "내용",
  "view_count": 150,        // 바로 추가
  "tags": ["tech", "mongodb"], 
  "metadata": {             // 중첩 구조도 자유롭게
    "device": "mobile",
    "browser": "chrome"
  }
}

실무에서 체감한 장점:

  • 기획 변경에 즉시 대응 가능
  • 복잡한 JOIN 없이도 풍부한 데이터 표현

2. JSON 친화적 개발 환경

현대 웹 개발은 대부분 JSON 기반입니다. MongoDB는 이 흐름에 완벽하게 맞아떨어집니다.

// API에서 받은 JSON을 그대로 저장
const userPost = {
  "title": req.body.title,
  "author": {
    "id": req.user.id,
    "name": req.user.name
  },
  "tags": req.body.tags.split(',')
};

// 별도 변환 없이 바로 저장
await posts.insertOne(userPost);

MySQL 쿼리 사고에서 벗어나기

GROUP BY에서 Aggregation Pipeline로

MySQL에서 익숙했던 복잡한 집계 쿼리입니다.

SELECT 
    author_name,
    COUNT(*) as post_count,
    AVG(LENGTH(title)) as avg_title_length
FROM posts 
WHERE created_at >= '2024-12-01'
GROUP BY author_name
HAVING post_count > 2
ORDER BY post_count DESC;

MongoDB Aggregation Pipeline로는 데이터 흐름을 단계별로 설계합니다.

[
  // 1단계: 필터링
  { $match: { "createdAt": { $gte: ISODate("2024-12-01") } } },
  
  // 2단계: 그룹화
  { $group: {
    "_id": "$author.name",
    "post_count": { $sum: 1 },
    "avg_title_length": { $avg: { $strLenCP: "$title" } }
  }},
  
  // 3단계: 조건 필터링
  { $match: { "post_count": { $gt: 2 } } },
  
  // 4단계: 정렬
  { $sort: { "post_count": -1 } }
]

핵심 차이점

  • MySQL: 한 번에 모든 조건을 작성
  • MongoDB
    • 데이터가 파이프라인을 흐르며 단계별 변환
    • 이 방식이 복잡해 보이지만, 실제로는 디버깅과 수정이 훨씬 쉽습니다. 각 단계별로 중간 결과를 확인할 수 있기 때문입니다.

MongoDB Compass: MySQL 개발자에게 친숙한 GUI 도구

MongoDB Compass가 뭔데?

MongoDB Compass는 MongoDB 공식 GUI 도구입니다. MySQL을 사용하면서 phpMyAdmin, MySQL Workbench 같은 도구들을 써보셨다면, Compass도 비슷한 역할을 한다고 생각하시면 됩니다.

MySQL GUI 도구와 비교

  • MySQL Workbench → MongoDB Compass
  • 테이블 브라우징 → 컬렉션 브라우징
  • SQL 쿼리 실행 → MongoDB 쿼리 실행
  • 스키마 디자인 → 문서 구조 분석

MongoDB Compass 실무 활용법

정규표현식을 활용한 강력한 텍스트 검색

MySQL의 LIKE 검색을 넘어서는 유연한 패턴 매칭이 가능합니다.

// 여러 키워드 동시 포함 (순서 무관)
{
  "content": { 
    $regex: "(?=.*MongoDB)(?=.*실무)", 
    $options: "i" 
  }
}

// 조건부 검색: '공지'는 포함하되 '삭제'는 제외
{
  "title": { 
    $regex: "(?=.*공지)(?!.*삭제)",
    $options: "i" 
  }
}

My Queries로 업무 효율성 높이기

자주 사용하는 검색 조건을 템플릿으로 저장하여 반복 작업을 줄일 수 있습니다.

// 일일 점검용 저장 쿼리들
"오늘_생성_데이터": { "createdAt": { $gte: "TODAY_START" } },
"데이터_품질_체크": { $or: [/* 필수 필드 누락 조건들 */] },
"특정_사용자_활동": { "author.name": "USER_TEMPLATE" }

실무에서 자주 마주치는 MongoDB 패턴

데이터 품질 검사

MySQL보다 훨씬 직관적으로 데이터 일관성을 검증할 수 있습니다.

// 필수 필드 누락 검사
{
  $or: [
    { "title": { $exists: false } },
    { "title": "" },
    { "author.name": { $exists: false } }
  ]
}

// 날짜 일관성 검사: 수정일이 생성일보다 이른 이상한 데이터
{
  $expr: { $lt: ["$updatedAt", "$createdAt"] }
}

배열 데이터 활용

관계형 DB에서는 복잡했던 다중 값 처리가 자연스럽습니다.

// 특정 태그 포함
{ "tags": "MongoDB" }

// 여러 태그 중 하나라도 포함
{ "tags": { $in: ["MongoDB", "NoSQL"] } }

// 태그가 2개 이상인 게시글
{ $expr: { $gte: [{ $size: "$tags" }, 2] } }

성능과 최적화 고려사항

Aggregation Pipeline 최적화

파이프라인 순서가 성능에 직접적인 영향을 미칩니다.

// ❌ 비효율적: 전체 데이터를 그룹화 후 필터링
[
  { $group: { /* 전체 데이터 그룹화 */ } },
  { $match: { "count": { $gt: 10 } } }
]

// ✅ 효율적: 필터링으로 데이터를 줄인 후 그룹화
[
  { $match: { "status": "active" } },
  { $group: { /* 줄어든 데이터만 그룹화 */ } }
]

데이터 모델링 사고의 전환

정규화에서 비정규화로

RDB의 정규화 원칙을버리고, 조회 패턴에 맞춰 데이터를 구성합니다.

MySQL 방식 (정규화)

// 별도 테이블로 분리
users: id, name, email
posts: id, title, content, user_id

MongoDB 방식 (비정규화)

// 자주 함께 조회되는 데이터는 임베딩
{
  "title": "게시글",
  "content": "내용",
  "author": {           // 사용자 정보 임베딩
    "id": ObjectId("..."),
    "name": "김머호",
    "email": "daeho@example.com"
  }
}

이 방식은 JOIN 없이도 필요한 모든 정보를 한 번에 가져올 수 있어 성능상 유리합니다.

마무리

MongoDB는 단순히 "스키마가 없는 데이터베이스"가 아닙니다. 데이터를 바라보는 관점 자체를 바꾸는 도구입니다.

MySQL의 엄격한 구조에서 벗어나 더 유연하고 직관적인 데이터 처리가 가능해집니다. 특히 JSON 기반 API가 표준이 된 현재 환경에서, MongoDB의 문서 기반 접근법은 개발 생산성을 크게 향상시켜줍니다.

중요한 것은 MySQL의 사고방식을 완전히 버리는 것이 아니라, 상황에 맞는 적절한 도구를 선택하는 판단력을 기르는 것입니다. 복잡한 관계형 데이터나 강한 일관성이 필요한 경우에는 여전히 MySQL이 더 적합할 수 있습니다.

저와 같은 환경에 계신 분들에게 조금이라도 도움이 되는 글이 되었으면 좋겠습니다. 감사합니다.

profile
안녕하세요. 멋쟁이 백엔드 개발자입니다😎😎

0개의 댓글