Choorai
Lv.2

NoSQL 데이터베이스

스키마를 미리 정의하지 않고 유연하게 데이터를 저장합니다. JSON과 유사한 문서(Document) 형태가 대표적입니다.

이게 뭐야?

스키마 없이 JSON 형태로 데이터를 저장. 유연한 구조.

1언제 필요해?

  • 데이터 구조가 자주 변경될 때 (프로토타이핑, MVP)
  • 중첩된 데이터를 통째로 저장할 때 (블로그 포스트 + 댓글)
  • 수평 확장이 필요할 때 (대량 트래픽 처리)
  • 실시간 동기화가 필요할 때 (Firestore + 모바일 앱)

2주요 서비스

MongoDB Atlas

가장 인기

문서형 NoSQL의 대표. 클라우드 관리형(Atlas)으로 시작이 쉽습니다. 강력한 쿼리와 집계(aggregation) 파이프라인을 제공합니다.

Firestore

Firebase 내장

Google Firebase에 포함된 NoSQL DB. 실시간 리스너로 데이터 변경 시 클라이언트에 자동 반영됩니다.

DynamoDB

AWS

AWS의 완전 관리형 NoSQL. 키-값 및 문서 모델을 지원합니다. 대규모 트래픽에서 일관된 성능을 보장합니다.

3비용

  • MongoDB Atlas - 무료 티어 512MB 스토리지, 공유 클러스터
  • Firestore - 일 50K 읽기 / 20K 쓰기 / 20K 삭제 무료
  • DynamoDB - 월 25GB 스토리지, 25 읽기/쓰기 유닛 무료

4연결 예제

FastAPI + motor (Python, MongoDB)

app/database.py
# app/database.py
from motor.motor_asyncio import AsyncIOMotorClient

MONGO_URL = "mongodb+srv://user:[email protected]/mydb"

client = AsyncIOMotorClient(MONGO_URL)
db = client.mydb
app/main.py
# app/main.py
from fastapi import FastAPI
from app.database import db
from bson import ObjectId

app = FastAPI()

@app.get("/posts")
async def get_posts():
    posts = []
    async for post in db.posts.find().limit(20):
        post["_id"] = str(post["_id"])
        posts.append(post)
    return posts

@app.post("/posts")
async def create_post(title: str, content: str, tags: list[str] = []):
    doc = {"title": title, "content": content, "tags": tags}
    result = await db.posts.insert_one(doc)
    doc["_id"] = str(result.inserted_id)
    return doc

Hono + mongodb (TypeScript)

src/db.ts
// src/db.ts
import { MongoClient } from 'mongodb';

const MONGO_URL = 'mongodb+srv://user:[email protected]/mydb';
const client = new MongoClient(MONGO_URL);
const db = client.db('mydb');

export default db;
src/index.ts
// src/index.ts
import { Hono } from 'hono';
import db from './db';

const app = new Hono();

app.get('/posts', async (c) => {
  const posts = await db.collection('posts').find().limit(20).toArray();
  return c.json(posts);
});

app.post('/posts', async (c) => {
  const { title, content, tags } = await c.req.json();
  const result = await db.collection('posts').insertOne({
    title,
    content,
    tags: tags || [],
    createdAt: new Date(),
  });
  return c.json({ _id: result.insertedId, title, content, tags }, 201);
});

export default app;

RDB vs NoSQL 선택 기준

데이터 간 관계가 복잡하면 RDB, 데이터 구조가 자주 바뀌거나 빠른 개발이 우선이면 NoSQL이 적합합니다. 둘 다 사용하는 것도 흔한 패턴입니다.

마지막 업데이트: 2026년 2월 22일 · 버전: v0.0.1

피드백 보내기

입력한 내용으로 새 이슈 페이지를 엽니다.

GitHub 이슈로 보내기