취업 자료실MongoDB 스키마 설계 — 임베딩과 참조, 언제 무엇을 쓸까

MongoDB 스키마 설계 — 임베딩과 참조, 언제 무엇을 쓸까

2026년 10월 24일 5분 읽기 조회 0
MongoDB 스키마 설계 — 임베딩과 참조, 언제 무엇을 쓸까

MongoDB 설계의 출발점은 쿼리 패턴입니다. 공식 문서의 임베딩·참조 판단 기준, 16MiB 문서 한도 등 제한값, 주문·댓글·카테고리 사례와 설계 5단계를 정리했습니다.

MongoDB를 처음 쓰면 "스키마가 없다"는 말에 마음이 편해집니다. 테이블을 미리 정하지 않아도 되고, 문서마다 필드가 달라도 저장되니까요. 그런데 몇 달 뒤 쿼리가 느려지고 문서 하나가 끝없이 커지는 문제를 만나면, 그때 깨닫게 됩니다. MongoDB 스키마 설계는 사라진 것이 아니라 데이터베이스가 아닌 개발자의 몫으로 넘어왔다는 것을요.

이 글은 MongoDB 공식 문서의 데이터 모델링 기준을 바탕으로, 설계의 핵심 질문인 "임베딩(한 문서 안에 넣기)과 참조(다른 컬렉션에 두고 연결하기) 중 무엇을 쓸까"에 답하는 방법을 사례와 함께 정리합니다.

💡 스키마리스는 설계가 필요 없다는 뜻이 아니다

관계형 데이터베이스는 정규화로 중복을 없애고, 필요할 때 JOIN으로 합칩니다. 설계 기준이 "데이터의 구조"에 있습니다. MongoDB는 기준이 다릅니다. 데이터를 어떻게 읽고 쓰는지, 즉 애플리케이션의 쿼리 패턴이 설계의 출발점입니다. 함께 읽히는 데이터는 한 문서에 모으고, 따로 움직이는 데이터는 나누는 것이 기본 원리입니다.

이 원리가 중요한 이유는 원자성 때문입니다. 공식 문서는 "MongoDB의 쓰기 작업은 단일 문서 수준에서 원자적"이라고 설명합니다. 한 문서 안의 여러 하위 필드를 바꾸는 업데이트는 전부 성공하거나 전부 실패합니다. 여러 문서에 걸친 원자성이 필요하면 다중 문서 트랜잭션을 쓸 수 있지만, 공식 문서는 트랜잭션이 단일 문서 쓰기보다 성능 비용이 크며 "효과적인 스키마 설계를 대신해서는 안 된다"고 분명히 적고 있습니다.

📊 설계 전에 알아야 할 숫자들

설계 판단에 직접 영향을 주는 제한값이 있습니다. 공식 문서의 제한 및 임계값 페이지에서 확인한 내용입니다.

항목제한설계에 주는 의미
BSON 문서 최대 크기16MiB끝없이 커지는 배열을 한 문서에 넣으면 언젠가 한계에 닿음. 큰 파일은 GridFS 사용
문서 중첩 깊이최대 100단계과도한 중첩은 읽기·수정도 어려워짐
컬렉션당 인덱스최대 64개쿼리마다 인덱스를 만드는 식의 설계는 한계가 있음
복합 인덱스 필드 수최대 32개인덱스는 핵심 쿼리 중심으로

16MiB는 텍스트만 담으면 꽤 큰 용량이지만, 댓글·로그·센서 측정값처럼 시간이 갈수록 쌓이는 데이터를 배열로 계속 붙이면 생각보다 빨리 문제가 됩니다. 공식 문서는 또 큰 문서일수록 RAM을 많이 써서 디스크 읽기가 늘고 성능이 떨어질 수 있다고 경고합니다.

어두운 배경에 정육면체 블록들이 선으로 연결된 네트워크 그래픽

⚖️ 임베딩 vs 참조 — 공식 판단 기준

MongoDB 공식 문서는 두 방식을 고르는 기준을 다음처럼 정리합니다.

임베딩이 어울리는 경우참조가 어울리는 경우
"가진다"·"포함한다" 관계일 때자식 쪽 개수(카디널리티)가 많을 때
애플리케이션이 함께 조회할 때임베딩한 데이터가 끝없이 늘어날 때
함께 수정되는 데이터일 때합친 크기가 메모리·전송량에 부담될 때
같은 시점에 보관(아카이브)할 데이터일 때쓰기가 많은 환경에서 서로 다른 시점에 기록될 때
자식 데이터가 부모 없이도 독립적으로 존재할 때

정리하면 임베딩은 "읽을 때 한 번에, 바꿀 때 함께"인 데이터에, 참조는 "많거나, 계속 늘거나, 따로 사는" 데이터에 맞습니다. 중복도 금기가 아닙니다. 공식 문서는 데이터를 일부 중복하면 여러 컬렉션을 조인($lookup)할 필요가 없어져 성능이 좋아질 수 있고, 읽을 때마다 조인하는 비용이 가끔 일어나는 중복 데이터 갱신 비용보다 클 수 있다고 설명합니다.

💻 사례로 보는 설계 판단

사례 1. 주문과 배송지 — 임베딩

주문 문서 안에 배송지 주소와 주문 당시 상품명·가격을 넣습니다. 주문 상세 화면은 이 정보를 항상 함께 읽고, 회원이 나중에 주소를 바꿔도 과거 주문의 배송지는 그대로여야 하므로 "주문 시점의 사본"을 임베딩하는 것이 자연스럽습니다. 회원 컬렉션의 주소와 중복되지만, 이 중복은 의도된 기록입니다.

사례 2. 게시글과 댓글 — 참조(또는 묶음)

인기 글의 댓글은 수천 개까지 늘어날 수 있습니다. 끝없이 늘어나는 배열이므로 댓글은 별도 컬렉션에 두고 게시글 ID로 연결합니다. 목록 화면에 최근 댓글 3개만 보여 준다면, 그 3개만 게시글 문서에 사본으로 넣어 두는 절충도 가능합니다.

사례 3. 상품과 카테고리 — 참조 배열

한 상품이 여러 카테고리에 속하고, 카테고리 정보는 상품과 무관하게 이름이 바뀌거나 정렬 순서가 바뀝니다. 독립적으로 존재하는 데이터이므로 상품 문서에는 카테고리 ID 배열만 두고, 카테고리 상세는 별도 컬렉션에서 관리합니다.

책상 위 노트북 화면에 코드가 열려 있는 작업 공간

🗺️ 설계 순서 다섯 단계

  1. 쿼리 목록 작성: 화면과 API별로 "무엇을, 어떤 조건으로, 얼마나 자주" 읽고 쓰는지 적습니다. 읽기와 쓰기 비율도 함께 기록합니다.
  2. 함께 움직이는 데이터 묶기: 같은 화면에서 늘 같이 읽히고 같이 바뀌는 데이터를 한 문서 후보로 묶습니다.
  3. 성장 한계 점검: 묶은 데이터 중 개수가 계속 늘어나는 배열이 있는지 확인하고, 상한이 없다면 분리합니다.
  4. 인덱스 설계: 1단계의 핵심 쿼리 조건과 정렬 기준에 맞춰 인덱스를 만들고, 실행 계획(explain)으로 실제 사용 여부를 확인합니다.
  5. 검증 규칙 추가: 필수 필드와 자료형은 $jsonSchema 기반 스키마 검증으로 걸어 두어, 유연함이 무질서로 바뀌지 않게 합니다.

이 순서는 한 번으로 끝나지 않습니다. 서비스 기능이 바뀌면 쿼리 패턴이 바뀌고, 설계도 그에 맞춰 다시 봐야 합니다.

⚠️ 처음 설계할 때 흔히 하는 실수

  • 관계형 설계를 그대로 옮기기: 테이블 하나를 컬렉션 하나로 옮기면 화면 하나를 그릴 때마다 여러 번 조회하거나 $lookup을 반복하게 됩니다.
  • 모든 것을 한 문서에: 반대로 사용자 문서 안에 활동 로그를 계속 붙이면 문서가 커지고 수정 비용이 늘며 결국 16MiB 한도에 다가갑니다.
  • 트랜잭션으로 설계 땜질: 여러 문서를 늘 함께 바꿔야 한다면 트랜잭션을 늘리기 전에 그 데이터를 한 문서로 모을 수 있는지 먼저 봅니다.
  • 인덱스 없이 시작: 데이터가 적을 때는 티가 나지 않다가, 수십만 건을 넘기며 갑자기 느려집니다.

❓ 자주 묻는 질문 (FAQ)

Q1. MongoDB에도 JOIN이 있나요?

집계 파이프라인의 $lookup 단계로 다른 컬렉션을 결합할 수 있습니다. 다만 매 조회마다 쓰기보다는 자주 함께 읽는 데이터를 임베딩하는 설계를 먼저 고려하는 것이 일반적입니다.

Q2. 데이터 중복은 나쁜 것 아닌가요?

관계형 DB에서는 피하지만, MongoDB에서는 읽기 성능을 위해 의도적으로 중복을 둘 수 있습니다. 대신 원본이 바뀔 때 사본을 언제, 어떻게 갱신할지 규칙을 정해 둬야 합니다.

Q3. 16MiB를 넘을 것 같은 데이터는 어떻게 하나요?

계속 늘어나는 목록이라면 별도 컬렉션으로 분리하고, 이미지·동영상 같은 큰 파일은 GridFS나 별도 파일 저장소에 두고 경로만 저장합니다.

Q4. 스키마 검증을 걸면 MongoDB의 장점이 사라지지 않나요?

필수 필드와 자료형처럼 꼭 지켜야 할 규칙만 걸고, 나머지는 유연하게 두는 방식이 가능합니다. 유연함과 품질을 함께 챙기는 방법입니다.

Q5. 관계형 DB 경험이 있으면 MongoDB 배우기가 쉬운가요?

조회·인덱스·트랜잭션 개념이 그대로 도움이 됩니다. 다만 "정규화가 기본"이라는 습관을 "쿼리 패턴이 기본"으로 바꾸는 데 연습이 필요합니다.

📚 설계를 손으로 익히려면

설계 원칙은 실제 데이터를 넣고 조회해 볼 때 비로소 감이 옵니다. 누구나패스의 「누구나 쉽게 배우는 NoSQL-MongoDB」는 NoSQL 이해와 MySQL과의 비교에서 출발해 MongoDB 구성과 기본 개념, 기본 명령어, 조건 검색, CRUD, 집계 프레임워크, Text 검색과 인덱스, 모니터링, Python(pymongo) 애플리케이션 연동까지 10차시(총 5시간 29분)로 다룹니다. mongoimport로 코스피 주식 데이터를 가져와 다뤄 보고, 필드가 서로 다른 문서가 한 컬렉션에 저장되는 모습도 직접 확인합니다. 수강 기간은 결제 후 30일입니다.


임베딩과 참조를 실제 데이터로 비교해 보고 싶다면 NoSQL-MongoDB 과정 자세히 보기에서 차시 구성을 확인하세요.

다음 단계

읽은 내용을 과정으로 이어서 준비해 보세요

댓글

0/1000

불러오는 중...

관련 글