우당탕탕
MongoDB 처음 써보면서 RDBMS와 다른 점 직접 체험하며 정리해봤어요 본문
사실 이걸 처음 접했을 때, RDBMS랑 너무 다르고 익숙하지 않아서 엄청 헤맸어요. MongoDB 쿼리 구조도 그렇고, 데이터 모델링 방식도 달라서요. 이 글은 제가 실제 프로젝트에 MongoDB를 도입하면서 겪은 시행착오와 RDBMS와 비교했을 때 꼭 알아야 할 포인트들을 중심으로 작성했어요.
MongoDB 설치부터 기본 CRUD 쿼리 작성, 인덱스와 최적화 경험, 그리고 데이터 모델링 차이까지 모두 다룹니다. 실제 실행 결과도 보여드리니, 처음 접하는 분들도 따라 하면서 이해하기 좋으실 거예요.
개발 환경 / 버전 정보
저는 MongoDB 6.0 커뮤니티 버전을 사용했고, RDBMS는 MySQL 8.0과 비교했습니다. 데이터 모델링은 JSON 문서 형태가 익숙해지기까지 조금 시간이 걸렸어요.
MongoDB 기본 CRUD 이렇게 하면 됩니다
사실 이 부분이 가장 헷갈렸는데, MongoDB는 SQL이 아니라 자바스크립트 객체 형태로 쿼리 짜는 게 신기했어요.
// 컬렉션에 문서 삽입하기
db.users.insertOne({ name: "홍길동", age: 30, roles: ["admin", "user"] })
// 나이가 25 이상인 유저 조회
const results = db.users.find({ age: { $gte: 25 } }).toArray()
print(results)
// 특정 유저의 나이 업데이트
db.users.updateOne({ name: "홍길동" }, { $set: { age: 31 } })
// 나이가 30 이상인 문서 삭제
db.users.deleteMany({ age: { $gte: 30 } })
RDBMS에서 썼던 INSERT, SELECT, UPDATE, DELETE 대신 이렇게 객체 형태로 조건을 주고 명령하는 점이 가장 달랐어요. 실행 결과도 console.log 형태로 바로 확인할 수 있거든요.
SQL과 다르게 여기서 많이 틀립니다
많은 분들이 헷갈려하는 게 JOIN인데요, MongoDB는 기본적으로 JOIN 개념이 없어요. 대신 중첩 문서나 $lookup을 써야 해서 저도 여러 번 삽질했습니다.
// RDBMS JOIN과 비슷한 $lookup 예시
// orders 컬렉션과 users 컬렉션을 userId로 조인
const pipeline = [
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userInfo"
}
}
]
const joinedResults = db.orders.aggregate(pipeline).toArray()
print(joinedResults)
$lookup이 있긴 하지만 복잡도가 높고 성능도 RDBMS JOIN보다 떨어질 수 있어서, 저는 데이터 설계를 중첩 문서로 바꾸는 쪽으로 방향을 잡았어요.
인덱스 최적화, RDBMS와 달리 이렇게 해봤어요
MongoDB는 필드 단위로 인덱스를 만들고, 복합 인덱스도 비슷하게 만드는데, 쿼리 플랜 확인이 RDBMS보다 직관적이지 않아 고생했어요.
// age 필드에 인덱스 생성
db.users.createIndex({ age: 1 })
// 인덱스 사용 여부 확인
const explain = db.users.find({ age: { $gte: 25 } }).explain("executionStats")
printjson(explain.executionStats)
explain 결과를 보니 인덱스를 제대로 타는지, 스캔하는 문서 수가 몇 건인지까지 알 수 있어서 꽤 도움이 됐어요. RDBMS에서 익숙한 EXPLAIN과 용어는 비슷하지만 구조가 조금 달라 적응이 필요했죠.
여기서 삽질했던 부분들
가장 큰 문제는 스키마리스라서 처음에 문서 구조를 안 맞게 설계하다가 데이터 무결성이 깨졌던 거예요. RDBMS처럼 엄격하게 스키마가 없으니까, 입력할 때마다 필드가 달라지고 혼란스러웠거든요.
WriteResult({ "nInserted" : 1, "writeError" : { "code" : 121, "errmsg" : "Document failed validation" } })
// 스키마 검증을 위해 Validator 설정을 안 해놔서 엉망이었어요.
이걸 해결하려고 MongoDB 3.6 이상부터 지원하는 Schema Validation 기능을 써봤어요. JSON Schema 형태로 체크 가능해서 마음이 좀 놓였죠.
심화: 이런 점도 알고 쓰면 좋아요
MongoDB는 복제와 샤딩이 기본 내장되어서 수평 확장이 쉽다는 게 큰 장점인데, 그만큼 설정과 모니터링이 복잡할 수 있어요. 운영 환경에서는 모니터링 툴과 백업 전략도 꼭 챙겨야 한다는 걸 경험으로 깨달았습니다.
또한, 트랜잭션 지원은 4.0 버전부터 시작했지만 아직 RDBMS처럼 무조건 믿기 어려운 부분도 있어서 복잡한 작업은 나눠서 처리하는 게 안전하더라고요.
자주 물어보시는 것들
Q. MongoDB에서는 JOIN이 안 된다는데, 무조건 문서 중첩을 써야 하나요?
A. 꼭 그렇진 않아요. $lookup으로도 JOIN 역할은 가능하지만 복잡한 조인은 성능 저하가 크니까, 일반적으로는 자주 같이 조회하는 데이터는 한 문서에 중첩하는 게 좋습니다.
Q. 스키마리스라고 해서 데이터 무결성 관리 어떻게 하나요?
A. 스키마리스지만 Validator 기능으로 JSON Schema를 만들어 필드 타입, 필수 여부를 검증 할 수 있어요. 코드 레벨에서 Mongoose 같은 ODM 라이브러리로 검증하는 방법도 많이 씁니다.
Q. 대용량 데이터에 적합한가요? RDBMS보다 좋은 점은요?
A. 수평 확장과 빠른 쓰기 작업에 강해요. 특히 비정형 데이터 많거나 규모가 큰 서비스에서는 운영도 편하고 성능도 좋습니다. 다만 트랜잭션이 많고 관계형 쿼리가 많은 시스템엔 RDBMS가 더 맞을 때도 있어요.
MongoDB는 RDBMS와 비교할 때 개념과 쿼리 방식이 완전히 달라서 처음엔 적응이 필요해요. 하지만 실제 운영하면서 경험해보니 문서 지향 DB의 유연성과 확장성은 확실한 매력입니다. 만약 비정형 데이터 다루거나 대규모 확장성을 고민한다면 도전해볼 만한 선택이었어요.
'Database' 카테고리의 다른 글
| [MySQL] 트랜잭션 격리 수준(Isolation Level)에 대한 이해 (0) | 2024.09.22 |
|---|
