지난 시간에는 우리 컴퓨터에 MongoDB를 직접 설치하고 실행해보는 실습을 진행했습니다. 이제 MongoDB라는 도구를 사용할 준비가 되었으니, 이 도구를 가지고
어떻게 데이터를 잘 정리하고 저장할지
고민해볼 차례입니다. 이것을 바로 '데이터 모델링'이라고 합니다.
튼튼하고 사용하기 편리한 건물을 지으려면 좋은 설계도가 필요하듯이, 효율적이고 성능 좋은 애플리케이션을 만들려면 좋은 데이터 모델 설계가 필수적입니다.
MongoDB는 기존 관계형 데이터베이스와 다른 방식으로 데이터를 다루기 때문에, 그 특성에 맞는 모델링 방법을 이해하는 것이 중요합니다.
🚀
데이터의 기본 단위: 문서(Document)와 BSON 🔗
다시 한번 떠올려 봅시다. MongoDB는 데이터를
문서(Document)
라는 단위로 저장합니다.
이 문서는 우리가 흔히 아는 JSON(JavaScript Object Notation) 형식과 매우 유사하게 생겼습니다.
하지만 내부적으로 MongoDB는 JSON을 그대로 저장하는 것이 아니라,
BSON(Binary JSON)
이라는 형식으로 변환하여 저장합니다.
BSON은 JSON과 비슷하지만 몇 가지 중요한 차이점과 장점을 가집니다.
바이너리(Binary) 형식
: BSON은 이름처럼 텍스트가 아닌 이진 데이터 형식입니다. 컴퓨터가 더 빠르고 효율적으로 데이터를 읽고 쓸 수 있게 해줍니다.
다양한 데이터 타입 지원
: JSON이 지원하는 기본 타입(문자열, 숫자, 불리언, 배열, 객체) 외에도 날짜(Date), 이진 데이터(Binary Data), 고유 식별자(ObjectId) 등 더 많은 데이터 타입을 지원합니다.
예를 들어, 모든 MongoDB 문서에는 자동으로 _id 라는 고유한 식별자 필드가 생성되는데, 이 값은 보통 ObjectId라는 BSON 타입을 가집니다.
{
"_id" : ObjectId( "60c72b2f9b1d8a001c8e4d7c" ) , // BSON의 ObjectId 타입
"제목" : "나의 첫 블로그 글" ,
"작성일" : new Date( "2023-10-27T10:00:00Z" ) , // BSON의 Date 타입
"조회수" : 100 ,
"공개여부" : true
}
BSON 덕분에 MongoDB는 데이터를 더 효율적으로 저장하고 처리할 수 있으며, 더 풍부한 형태의 데이터를 다룰 수 있습니다.
🚀
정보를 담는 그릇: 컬렉션과 데이터베이스 🔗
이런 문서들은 어디에 담길까요? 바로
컬렉션(Collection)
입니다.
컬렉션은 관련 있는 문서들의 모음이며, 관계형 데이터베이스의 '테이블'과 비슷한 역할을 합니다.
하지만 중요한 차이점은 컬렉션에는
스키마(Schema)
, 즉 정해진 구조가 없다는 것입니다. (정확히는 스키마가 유연하다고 표현합니다.)
같은 컬렉션 안의 문서들이 서로 다른 필드를 가질 수 있습니다.
그리고 여러 컬렉션들을 모아 놓은 더 큰 단위가 바로
데이터베이스(Database)
입니다.
정리하면,
데이터베이스 > 컬렉션 > 문서
의 계층 구조를 가집니다.
🚀
데이터를 어떻게 연결할까? 내장 vs. 참조 (Embeded vs Referenced) 🔗
자, 이제 본격적으로 데이터 모델링의 핵심 질문에 도달했습니다.
서로 관련된 데이터를 어떻게 구성하고 연결하는 것이 좋을까요?
예를 들어, 블로그 게시글(Post)과 그 게시글에 달린 댓글(Comment) 데이터는 어떻게 저장해야 할까요?
👨💻
MongoDB에서는 크게 두 가지 방식을 사용합니다.
✅
1. 내장 방식: 하나로 합치기(Embedded) 🔗
이름 그대로, 관련된 데이터를
하나의 문서 안에 포함시키는
방식입니다.
위의 블로그 예시를 들면, 게시글 문서 안에 댓글 정보를 배열 형태로 함께 저장하는 것입니다.
// Posts 컬렉션의 문서 예시
{
"_id" : ObjectId( "...post_id..." ) ,
"제목" : "MongoDB 데이터 모델링 재미있어요!" ,
"내용" : "내장 방식과 참조 방식을 배우고 있습니다." ,
"작성자" : "김학생" ,
"댓글" : [ // 댓글 정보를 배열로 내장
{
"_id" : ObjectId( "...comment_id_1..." ) ,
"작성자" : "이선생" ,
"내용" : "설명이 귀에 쏙쏙 들어오네요!" ,
"작성일" : new Date(...)
},
{
"_id" : ObjectId( "...comment_id_2..." ) ,
"작성자" : "박동료" ,
"내용" : "저도 동의합니다!" ,
"작성일" : new Date(...)
}
// ... 더 많은 댓글
]
}
관련된 데이터를 한 번의 데이터베이스 조회(쿼리)로 가져올 수 있어 읽기 성능이 좋습니다
.
하나의 문서 안에서 데이터 변경이 이루어지므로 데이터 일관성을 유지하기 쉽습니다
. (원자적 연산 가능)
내장된 데이터가 많아지면 문서 전체 크기가 너무 커질 수 있습니다
. (MongoDB는 개별 문서 크기에 제한이 있습니다. 현재 기준 16MB)
내장된 배열의 특정 항목만 자주 업데이트해야 하는 경우 비효율적일 수 있습니다.
데이터 간의 관계가 '일대소수(One-to-Few)' 또는 '일대다수(One-to-Many)' 이면서, '자식' 데이터(댓글)가 '부모' 데이터(게시글) 없이는 의미가 없거나 항상 함께 조회될 때 유리합니다.
데이터를 한 번에 읽어오는 것이 중요할 때 좋습니다.
✅
2. 참조 방식: 서로 연결하기 (Referenced) 🔗
이 방식은 관계형 데이터베이스와 비슷하게, 관련된 데이터를
별도의 컬렉션에 저장
하고 문서 간에
고유 ID(보통 _id)
를 사용하여 서로 연결(참조)하는 방식입니다. '정규화(Normalization)'와 유사한 접근 방식입니다.
위의 블로그 예시를 다시 보면, 게시글은 'Posts' 컬렉션에, 댓글은 별도의 'Comments' 컬렉션에 저장하고 서로 연결합니다.
// Posts 컬렉션의 문서
{
"_id" : ObjectId( "...post_id..." ) ,
"제목" : "MongoDB 데이터 모델링 재미있어요!" ,
"내용" : "내장 방식과 참조 방식을 배우고 있습니다." ,
"작성자" : "김학생"
// 댓글 정보는 여기에 없음
}
// Comments 컬렉션의 문서들
{
"_id" : ObjectId( "...comment_id_1..." ) ,
"postId" : ObjectId( "...post_id..." ) , // 어떤 게시글에 대한 댓글인지 참조 ID 저장
"작성자" : "이선생" ,
"내용" : "설명이 귀에 쏙쏙 들어오네요!" ,
"작성일" : new Date(...)
},
{
"_id" : ObjectId( "...comment_id_2..." ) ,
"postId" : ObjectId( "...post_id..." ) , // 같은 게시글 참조
"작성자" : "박동료" ,
"내용" : "저도 동의합니다!" ,
"작성일" : new Date(...)
}
Comments 상자 안의 문서에서 Posts 상자의 특정 문서를 참조
데이터 중복을 줄일 수 있습니다. (예: 사용자 정보를 별도 컬렉션에 두고 ID로 참조)
문서 크기가 너무 커지는 것을 방지할 수 있습니다.
자주 업데이트되는 데이터를 분리하여 관리하기 용이합니다.
'다대다(Many-to-Many)' 관계를 표현하기에 더 적합합니다.
데이터 간의 관계가 '일대다수(One-to-Many)' 이지만 '다수' 쪽 데이터가 매우 많거나(One-to-Squillions), 또는 '다대다(Many-to-Many)' 관계일 때 유리합니다.
참조되는 데이터(예: 상품 정보, 사용자 정보)가 독립적으로 존재하고 자주 업데이트될 때 좋습니다.
개별 문서 크기를 작게 유지해야 할 때 사용합니다.
내장 방식과 참조 방식 중 어느 것이 절대적으로 좋다고 말할 수는 없습니다.
상황에 따라, 그리고
애플리케이션이 데이터를 어떻게 사용할지(데이터 접근 패턴)
에 따라 최적의 선택이 달라집니다.
다음과 같은 점들을 고려하여 결정해야 합니다.
데이터 간의 관계
: 일대소수인가, 일대다수인가, 다대다인가?
데이터 접근 빈도
: 함께 자주 조회되는가, 아니면 개별적으로 조회되는 경우가 많은가? (읽기 성능 중요도)
데이터 크기
: 내장했을 때 문서 크기 제한을 넘을 가능성은 없는가?
데이터 업데이트 빈도
: 자주 변경되는 데이터인가? (쓰기 성능/효율성 중요도)
데이터 일관성
: 데이터가 항상 함께 일관성을 유지해야 하는가?
실제로는 이 두 방식을 혼합하여 사용하는 경우도 많습니다. 예를 들어, 댓글의 일부 정보(작성자 이름, 작성일)만 게시글에 내장하고, 전체 댓글 내용은 필요할 때만 참조 방식으로 가져오는 '하이브리드' 접근도 가능합니다.
Embedding
Referencing
장점
✔ 데이터 조회가 빠름 ✔ 중복된 데이터 없음 ✔ 트랜잭션을 한 번에 처리 ✔ 여러 문서에 저장 가능 ✔ 관련 데이터를 직관적으로 파악 ✔ 연관성이 낮은 데이터 단점
✖ 중복된 데이터 ✖ 데이터 조회가 느림 ✖ 문서 크기가 큼 ✖ 트랜잭션 처리가 복잡 고려사항
✔ 데이터 관계가 '하나에 여러 개' ✔ 데이터 관계가 '여러 개에 여러 개'
오늘은 MongoDB에서 데이터를 효과적으로 구성하는 방법, 즉 데이터 모델링에 대해 알아보았습니다.
BSON 기반의 유연한 문서 구조를 이해하고, 데이터를 설계하는 두 가지 주요 접근 방식인
내장(Embedded)
방식과
참조(Referenced)
방식의 특징과 장단점을 비교하며 살펴보았습니다.
좋은 데이터 모델링은 애플리케이션의 성능과 확장성에 큰 영향을 미칩니다. 따라서 개발 초기 단계부터 데이터가 어떻게 사용될지를 신중하게 고려하여 모델을 설계하는 것이 매우 중요합니다.
다음 시간에는 실제로 MongoDB에 데이터를
만들고(Create), 읽고(Read), 수정하고(Update), 삭제하는(Delete)
, 이른바
CRUD
작업 방법에 대해 자세히 알아보겠습니다.