MySQL과 MongoDB는 데이터를 조작하는 방식에서 근본적인 차이를 보인다.
MySQL 은 전통적인 SQL 쿼리 언어를 사용하는 반면, MongoDB는 API 호출 방식의 접근법을 취한다.
이 글에서 실제 개발에서 자주 사용되는 쿼리를 비교하며 각각의 특징과 장단점을 살펴본다.
1. 데이터 삽입 (INSERT)
MySQL 방식
INSERT INTO users(id, name, department) VALUES(1001, '김철수', '컴퓨터');
MongoDB 방식
db.users.insertOne({
id: 1001,
name: "김철수",
department: "컴퓨터"
});
핵심 차이점
MySQL : 구조화된 쿼리 언어
- 전통적인 SQL 문법 사용
- 테이블과 컬럼 구조가 명확히 정의됨
- INSERT, VALUES 키워드 사용
MongoDB : API 호출 방식
- db 라는 객체를 통해 데이터 베이스 접근
- 컬렉션(테이블에 해당)을 메서드로 호출
- JSON 형태의 문서로 데이터 삽입
데이터 유효성 검사의 차이
MySQL: 엄격한 스키마 검증
-- 테이블 생성 시 제약 조건 정의
CREATE TABLE users (
id INT NOT NULL,
name VARCHAR(50) NOT NULL,
department VARCHAR(50),
email VARCHAR(100) UNIQUE
);
-- NOT NULL 제약이 있는 필드에 값이 없으면 INSERT 실패
INSERT INTO users(id, department) VALUES(1001, '컴퓨터');
-- ERROR: Field 'name' doesn't have a default value
MongoDB: 스키마리스의 자유로움
// 어떤 필드가 빠져도 성공적으로 삽입
db.users.insertOne({
id: 1001,
department: "컴퓨터"
// name 필드가 없어도 성공
});
// 심지어 정의되지 않은 필드도 자유롭게 추가 가능
db.users.insertOne({
id: 1001,
name: "김철수",
department: "컴퓨터",
"이게_무슨값이야": "그러게..",
"임의의_필드": "자유롭게 추가 가능",
"중첩된_객체": {
"hobby": "독서",
"skills": ["JavaScript", "Python"]
}
});
MongoDB의 스키마리스 특성:
- 클라이언트에서 전송하는 모든 데이터가 그대로 저장
- 필드 누락이나 추가에 대한 제약 없음
- 개발 단계에서 빠른 프로토타이핑 가능
데이터 조회 (SELECT)
MySQL 방식
-- 기본 조회
SELECT * FROM users WHERE department = '컴퓨터';
-- 특정 필드만 조회
SELECT id, name FROM users WHERE department = '컴퓨터';
-- 조건이 복잡한 경우
SELECT * FROM users
WHERE department = '컴퓨터' AND name LIKE '김%'
ORDER BY id DESC
LIMIT 10;
MongoDB 방식
// 기본 조회
db.users.find({department: "컴퓨터"});
// 특정 필드만 조회 (projection)
db.users.find(
{department: "컴퓨터"},
{id: 1, name: 1, _id: 0}
);
// 조건이 복잡한 경우
db.users.find({
department: "컴퓨터",
name: /^김/
}).sort({id: -1}).limit(10);
문법 비교:
- MySQL: WHERE, ORDER BY, LIMIT 등 키워드 사용
- MongoDB: 메서드 체이닝 방식으로 조건 추가
데이터 수정 (UPDATE)
MySQL 방식
-- 단일 레코드 수정
UPDATE users SET department = 'TEST' WHERE id = 1001;
-- 여러 필드 동시 수정
UPDATE users
SET department = 'TEST', name = '김철수수정'
WHERE id = 1001;
-- 조건에 맞는 모든 레코드 수정
UPDATE users SET department = 'IT' WHERE department = '컴퓨터';
// 단일 문서 수정
db.users.updateOne(
{id: 1001}, // 조건
{$set: {department: "TEST"}} // 수정할 내용
);
// 여러 필드 동시 수정
db.users.updateOne(
{id: 1001},
{$set: {
department: "TEST",
name: "김철수수정"
}}
);
// 조건에 맞는 모든 문서 수정
db.users.updateMany(
{department: "컴퓨터"},
{$set: {department: "IT"}}
);
MongoDB의 업데이트 연산자:
- $set: 필드 값 설정
- $inc: 숫자 필드 증가/감소
- $push: 배열에 요소 추가
- $pull: 배열에서 요소 제거
join 쿼리
SELECT s.name, g.course FROM users AS s JOIN grades ON s.id = grades.users_id WHERE s.name = '김철수'
db.users.find({name: "김철수"}, {name : 1. grades.course : 1})
컬렉션이 분리되어 있다면 lookup 이라는 조인하는 행위를 한다.
MongoDB의 철학:
- 조인(Lookup)은 성능상 비효율적
- 내장 문서 방식으로 설계하여 조인 최소화
- 한 번의 쿼리로 모든 관련 데이터 조회
실무에서의 선택 기준
MySQL이 적합한 상황
금융 시스템
-- 계좌 이체 트랜잭션 (ACID 보장 필수)
BEGIN;
UPDATE accounts SET balance = balance - 100000 WHERE account_id = 'A001';
UPDATE accounts SET balance = balance + 100000 WHERE account_id = 'A002';
INSERT INTO transactions (from_account, to_account, amount, timestamp)
VALUES ('A001', 'A002', 100000, NOW());
COMMIT;
이커머스 시스템
-- 주문 처리 시 재고 확인 및 차감
UPDATE products
SET stock = stock - 1
WHERE id = 1001 AND stock > 0;
-- 복잡한 주문 내역 조회
SELECT
o.order_id,
u.name as customer_name,
p.product_name,
oi.quantity,
oi.price
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE o.status = 'completed';
MySQL의 강점:
- 데이터 구조가 명확하고 변경이 적음
- 트랜잭션 무결성이 중요
- 복잡한 관계와 제약조건 필요
- 정확성이 성능보다 우선
MongoDB가 적합한 상황
대용량 로그 시스템
// 사용자 행동 로그 - 구조가 다양하고 대용량
db.user_logs.insertOne({
user_id: "user123",
timestamp: new Date(),
action: "page_view",
page: "/products/electronics",
device: "mobile",
session_data: {
browser: "Chrome",
os: "Android",
screen_size: "1920x1080",
referrer: "https://google.com"
},
custom_events: [
{event: "scroll", position: 50},
{event: "click", element: "buy_button"}
]
});
콘텐츠 관리 시스템
// 블로그 포스트 - 유연한 구조
db.posts.insertOne({
title: "MongoDB 사용기",
content: "...",
author: "김개발",
tags: ["database", "mongodb", "nosql"],
metadata: {
word_count: 1500,
read_time: 7,
seo_keywords: ["mongodb", "nosql"]
},
comments: [
{
author: "댓글러",
content: "좋은 글이네요!",
timestamp: new Date(),
likes: 5
}
]
});
MongoDB의 강점:
- 데이터 구조가 자주 변경됨
- 대용량 데이터 처리 성능 중요
- 수평적 확장(샤딩) 필요
- 빠른 개발 속도 요구
쿼리 성능 비교
| 작업 유형 | MySQL | MongoDB | 설명 |
| 단순 조회 | ⭐⭐⭐ | ⭐⭐⭐⭐ | MongoDB가 약간 유리 |
| 복잡한 JOIN | ⭐⭐⭐⭐⭐ | ⭐⭐ | MySQL이 압도적 |
| 대용량 삽입 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | MongoDB가 압도적 |
| 트랜잭션 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | MySQL이 더 안정적 |
| 집계 연산 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 비슷한 수준 |
개발 생산성 비교
| 측면 | MySQL | MongoDB |
| 학습 곡선 | 보통 (SQL 표준) | 쉬움 (JavaScript 친숙) |
| 프로토타이핑 | 느림 (스키마 정의 필요) | 빠름 (스키마리스) |
| 스키마 변경 | 어려움 (ALTER TABLE) | 쉬움 (필드 추가/삭제) |
| 디버깅 | 쉬움 (표준 도구) | 보통 (MongoDB 전용 도구) |