2025. 7. 9. 20:10ㆍDataBase

이번 포스팅에서는 NoSQL의 대표적인 데이터베이스인 MongoDB 연동에 대해서 알아보겠습니다.
NoSQL 데이터베이스?
| 항목 | 설명 |
| 비관계형 (Non-relational) | 테이블 간의 관계(조인)가 없거나 최소화됨. 대신 중첩 구조, 중복 데이터 등을 허용하여 성능과 유연성 확보 |
| 스키마 유연성 | 고정된 스키마가 없음. 각 문서나 레코드는 구조가 달라도 저장 가능 (MongoDB에서는 같은 컬렉션 내 문서 구조가 달라도 됨) |
| 수평 확장 | 여러 서버에 데이터를 분산해 저장(sharding). 수평적 확장(scale-out)이 쉬워 대용량 데이터 처리에 유리 |
| 빠른 쓰기/읽기 작업 | 단순한 읽기·쓰기 작업에 매우 빠름. 실시간 데이터 처리, 로그 수집, IoT 등에서 강점 |
| 다양한 데이터 모델 | Key-Value, Document, Column-Family, Graph 등 다양한 저장 모델이 존재함 |
| 대규모 데이터 처리에 적합 | 정규화보다는 빠른 접근성과 유연성을 우선시하여 빅데이터나 비정형 데이터 처리에 적합 |
NoSQL 데이터 모델 유형 ?
| 유형 | 예시 DB | 특징 |
| Key-Value | Redis, DynamoDB | 빠른 조회, 캐시 또는 세션 저장 |
| Document | MongoDB, CouchDB | JSON 또는 BSON 문서 기반, 유연한 구조 |
| Column-family | Cassandra, HBase | 열 기반 저장, 분산 처리 최적화 |
| Graph | Neo4j, ArangoDB | 노드-간 관계 표현에 최적, 추천·소셜 네트워크 등에 강함 |
NoSQL이 적합한 상황
- 스키마가 자주 바뀌거나 유동적인 경우
- 대량의 비정형 데이터를 빠르게 저장/조회해야 할 때
- 빠른 개발/배포 주기를 요구하는 스타트업 환경
- 조인이 많지 않고 단건 조회/삽입 위주일 때
대표적인 NoSQL 데이터베이스
| DB | 설명 |
| MongoDB | 가장 널리 사용되는 Document DB. JSON/BSON 문서 기반 |
| Redis | 인메모리 Key-Value DB. 캐시, 세션 저장에 탁월 |
| DynamoDB | AWS의 완전관리형 Key-Value/문서 DB |
| Cassandra | 대용량 분산 Column-family DB |
| Neo4j | 관계 중심의 Graph DB |
MongoDB 데이터베이스 생성과정
우선 몽고디비 사이트에 접속해 로그인 혹은 회원가입 과정을 거친 후 데이터 베이스 생성과정을 시작합니다.

우선 테스트용으로 진행할 예정이기 때문에 Free 버전을 선택하고 데이터베이스 이름을 입력해줍니다.

그 후 연결 과정에서 데이터 베이스 사용자를 생성합니다.
이 때 처음으로 생성되는 사용자는 admin 계정입니다. 추후에 사용자를 추가할 수 있습니다.

그 다음 드라이버 연결을 선택해주고 몽고디비를 연결할 프로젝트 언어 스택에 맞춰서 설정해줍니다.
그 후 창에 표시되는 url을 복사해두었다가 프로젝트 코드에 추가해줍니다.
프로젝트 코드 & 생성된 MongoDB 연동과정
우선 몽고디비 연동에 필요한 "pymongo" 패키지를 설치해줍니다.
python -m pip install "pymongo[srv]==3.12"
다음은 몽고디비 연결 로직이 포함된 예시 코드입니다.
from pymongo import MongoClient
# Atlas 접속 URI
MONGO_URI = "your mongo uri"
client = MongoClient(MONGO_URI)
db = client["database_name"] # 데이터베이스
collection = db["collection_name"] # 컬렉션
# ... 기존 로직
# MongoDB 저장
if all_docs:
collection.insert_many(all_docs)
print(f"\n✅ {len(all_docs)}건의 도큐먼트가 MongoDB에 저장되었습니다.")
else:
print("❌ 저장할 데이터가 없습니다.")
db = client["database_name"] 부분에는 처음에 몽고디비 데이터베이스 생성과정에서 사용했었던 데이터베이스 이름을 넣어주면 됩니다.
collection = db["collection_name"] 부분에는 생성했던 데이터베이스 안에 생기는 논리적 스키마를 지칭하는 부분입니다.
그 전에 데이터베이스만 생성하고 그 밑의 컬렉션은 한개도 생성하지 않았기 때문에 아무것도 없는 상황일 것 입니다.
따라서 생성하고 싶은 컬렉션 이름을 넣고 코드를 실행하면 몽고디비에서 자동적으로 해당 컬렉션을 생성해줍니다.
collections.insert_many(documents, ordered=True)
collection.insert_many()는 MongoDB에서 여러 문서(document)를 한 번에 삽입할 때 사용하는 메서드입니다.
python의 pymongo 라이브러리에서 제공되며, 성능과 코드 간결성 면에서 자주 쓰입니다.
| 파라미터 | 설명 |
| documents | 삽입할 문서(dict)의 리스트. 리스트 자료형이 필수 입니다. |
| ordered (기본값: True) | True: 문서를 순서대로 삽입, 중간에 오류 나면 중단, False: 중간에 오류가 나도 나머지 계속 삽입 |
몽고디비에 데이터 삽입 시 주의 할 점은 _id 충돌입니다.
데이터를 삽입할 때 따로 _id 값을 지정하지 않으면 몽고디비에서 자동으로 id생성을 진행합니다.
다음과 같이 _id 필드에 ObjectId로 생성합니다. 해당 값은 고유한 값으로 primary key와 같은 역할을 합니다.

하지만 임의로 _id 값을 지정해서 사용하고 싶다면 서로 충돌이 안나도록 어플리케이션 코드부분에서 조정해주어야합니다.
만약 충돌이 난다면, 해당 데이터는 삽입에 실패합니다.
MongoDB쿼리 규칙
기본 쿼리 문법 규칙
MongoDB의 쿼리는 JSON 형태를 기반으로 합니다.
{ <field>: <value> } // 단순 조건
{ <field>: { <operator>: <value> } } // 조건 연산자 사용
비교 연산자
| 연산자 | 의미 | 예시 |
| $eq | 같다 (equal) | { "rank": { "$eq": 1 } } |
| $ne | 같지 않다 | { "category": { "$ne": "스킨케어" } } |
| $gt | 초과 | { "discount_price": { "$gt": 20000 } } |
| $gte | 이상 | { "timestamp": { "$gte": ISODate("2025-07-01") } } |
| $lt | 미만 | { "rank": { "$lt": 10 } } |
| $lte | 이하 | { "rank": { "$lte": 5 } } |
논리 연산자
| 연산자 | 의미 | 예시 |
| $and | 모두 만족 | { "$and": [ { "category": "스킨케어" }, { "rank": 1 } ] } |
| $or | 하나라도 만족 | { "$or": [ { "rank": 1 }, { "rank": 2 } ] } |
| $not | 부정 | { "rank": { "$not": { "$gte": 5 } } } |
문자열 검색
| 정확히 일치 | { "name": "심쿵틴트" } |
| 부분 일치 (정규표현식) | { "name": { "$regex": "심쿵" } } |
| 대소문자 구분 없이 | { "name": { "$regex": "심쿵", "$options": "i" } } |
날짜/시간 비교
{ "timestamp": { "$gte": ISODate("2025-07-01T00:00:00Z") } }
정렬, 제한, 선택 필드 (Atlas UI나 Compass에서 설정 가능)
- 정렬 (sort)
- db.collection.find({}).sort({ "timestamp": -1 }) // 최신순
- 필드 선택 (projection)
- db.collection.find({}, { "name": 1, "rank": 1, "_id": 0 }) // 원하는 필드만 보기
- 갯수 제한 (limit)
- db.collection.find({}).limit(10) // 상위 10개
예시로 category가 "전체"이면서 rank가 1인 것을 필터링하면서 다음과 같이 데이터를 조회할 수 있습니다.

'DataBase' 카테고리의 다른 글
| [Database] Spring Data Redis에서 Pipeline 활용하기 (0) | 2025.12.29 |
|---|---|
| [DataBase] DeadLock 해결하기, JPA 쿼리 실행 순서 (0) | 2025.04.18 |