SQL vs NoSQL — 무엇이 다르고 언제 무엇을 고르나
관계형(SQL)과 NoSQL의 차이를 데이터 저장 방식부터 비교하고, SQLite·Postgres·MongoDB·Firestore가 각각 어디에 속하는지, 댓글 같은 실제 기능엔 무엇이 맞는지 정리했다.
SQL vs NoSQL — 무엇이 다르고 언제 무엇을 고르나
블로그에 댓글 기능을 붙일 DB를 고를 때 "SQL이냐 NoSQL이냐"를 다시 짚게 됐다. 이름은 익숙한데 막상 "뭐가 다르냐"를 한 줄로 답하기 애매한 주제라, 기초부터 정리한다.
이름부터: NoSQL = "Not Only SQL"
- SQL = 관계형 데이터베이스(RDBMS). 데이터를 표(테이블)에 저장하고 SQL 언어로 다룬다.
- NoSQL = "SQL만 쓰는 게 아니다". 표가 아닌 다른 구조(문서·키값·그래프 등)로 저장하는 DB들의 통칭.
핵심 차이는 데이터를 어떻게 저장하느냐다.
저장 방식의 차이
SQL (관계형) — 엑셀 표처럼
컬럼이 미리 정해진 표에 행 단위로 저장한다.
comments 테이블
┌──────┬─────────────┬──────────┬─────────────┐
│ id │ author_name │ content │ created_at │
├──────┼─────────────┼──────────┼─────────────┤
│ 1 │ 홍길동 │ 안녕 │ 2026-06-21 │
│ 2 │ ㅇㅇ │ ㅋㅋ │ 2026-06-21 │
└──────┴─────────────┴──────────┴─────────────┘→ PostgreSQL, MySQL, SQLite
NoSQL (문서형) — JSON 덩어리처럼
스키마가 고정되지 않은 JSON 문서를 그대로 넣는다. 문서마다 모양이 달라도 된다.
{ "id": "abc", "author": "홍길동", "content": "안녕" }
{
"id": "def", "author": "ㅇㅇ", "content": "ㅋㅋ",
"likes": 5, // 이 문서에만 있는 필드
"replies": [{ "author": "김", "content": "ㄷㄷ" }] // 중첩 구조
}→ MongoDB, Firebase Firestore, DynamoDB
한눈에 비교
| SQL (관계형) | NoSQL (문서형) | |
|---|---|---|
| 저장 형태 | 정해진 표 | 자유로운 JSON |
| 스키마 | 미리 고정 | 유연 (문서마다 달라도 됨) |
| 관계 표현 | 테이블 간 JOIN | 중첩하거나 직접 연결 |
| 복잡한 조회 | 강력 (SQL) | 상대적으로 약함 |
| 확장 방식 | 수직(서버 키우기)에 강함 | 수평(서버 늘리기)에 강함 |
| 트랜잭션 | 강력 (ACID) | 제한적 (제품마다 다름) |
| 대표 | PostgreSQL, MySQL | MongoDB, Firestore |
"DB 없이 SQL"? — SQLite의 위치
자주 헷갈리는 지점. SQLite는 SQL 문법을 그대로 쓰지만 별도 DB 서버 프로세스가 없다. 파일 하나가 곧 DB이고, 라이브러리가 그 파일을 직접 읽고 쓴다.
일반 DB (Postgres/MySQL): 서버 프로세스가 항상 떠 있음 → 접속해서 쿼리
SQLite: 파일 하나(app.db)가 DB. 서버 없음, 라이브러리가 처리그래서 Cloudflare D1, Turso 같은 서비스가 "서버 관리 없이 SQLite를 클라우드에서" 제공한다 — "DB 없이 SQL 쓰는 느낌"에 가장 가깝다. 단, SQLite도 결국 쓰기를 받아줄 어딘가는 필요하다. 데이터를 저장할 곳이 0이면 SQL이든 NoSQL이든 불가능하다.
무엇을 언제 고르나
SQL이 유리한 경우
- 데이터 구조가 명확하고 안정적 (댓글: 이름·내용·시간·IP 등 컬럼이 뻔함)
- 관계·집계 조회가 많음 ("이 글의 댓글을 시간순으로", "같은 IP 60초 내 N개" 같은 카운트)
- 트랜잭션 정합성이 중요 (결제, 재고)
NoSQL이 유리한 경우
- 스키마가 자주 바뀌거나 문서마다 구조가 다름
- 실시간 동기화가 기본 필요 (Firestore)
- 초대규모 수평 확장이 필요 (글로벌 서비스)
실제 선택 — 댓글엔 SQL
블로그 댓글/조회수/방명록엔 SQL(PostgreSQL, Supabase)을 골랐다.
- 댓글 데이터는 컬럼이 명확해서 표 구조에 완벽히 맞는다.
- "시간순 정렬", "같은 IP 도배 카운트" 같은 집계가 SQL로 깔끔하다.
- Postgres는 표준 SQL이라 나중에 다른 DB로 이전하기도 쉽다(
pg_dump→ restore).
참고로 Firebase Firestore(NoSQL)는 무료 티어가 "용량"보다 "하루 읽기 횟수"가 먼저 걸려서, 조회가 많은 블로그엔 오히려 불리할 수 있다. 같은 무료라도 제한의 종류가 다르다.
정리
- SQL = 정해진 표 + JOIN·집계 강함 → 구조가 명확한 데이터에 적합
- NoSQL = 자유로운 JSON + 유연·실시간·초대규모 → 구조가 자주 바뀌거나 거대한 데이터에 적합
- SQLite = SQL이지만 서버 없는 파일 DB (D1·Turso가 이 계열)
- 댓글처럼 구조가 명확한 기능은 SQL이 기본값으로 무난하다
이 DB로 블로그 댓글을 어떻게 붙였는지는 정적 블로그에 동적 기능 더하기에 정리했다.
Next
다음 글이 없습니다.
Related Posts
같이 읽으면 좋은 글
새 댓글 알림을 무료로 — Discord·Slack·Telegram 웹훅 비교
서버에서 이벤트가 생길 때 폰으로 즉시 알림을 받고 싶다면 메신저 웹훅이 가장 가볍다. Discord·Slack·Telegram·이메일(Resend)의 무료 웹훅을 셋업 난이도와 코드까지 비교했다.
Prometheus 시리즈 ④ 프론트 — 데이터를 uPlot 차트로 그리기
Prometheus 응답을 uPlot의 AlignedData로 바꾸는 변환과, 명령형 uPlot을 React에 얹는 법. 행 지향 vs 열 지향 데이터 형식 차이, 문자열·타임스탬프 함정, 인스턴스 재생성 원칙을 정리하며 시리즈를 마친다.
Prometheus 시리즈 ③ 셋업 — node_exporter부터 CORS까지 직접 구축하기
빈 서버에서 Prometheus가 도는 상태까지. node_exporter 설치, prometheus.yml 작성, 가장 헤매기 쉬운 name 라벨 함정, targets→graph→API 검증, 브라우저 직접 호출 시의 CORS·인증까지 직접 구축하며 정리했다.