| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- git
- 차이점
- 힘들었던 한주
- Main
- 서버 컴포넌트
- Mac
- api 라우트
- fetch pull 차이
- axios
- git flow finish
- AJAX
- 끝까지 잘 마무리하기
- 다시 홧팅
- 바닐라JS
- 개발일지
- jQuery
- 실무는 공식문서로
- CSS
- 책으론 원리만
- HTML
- 클라이언트 컴포넌트
- JavaScript
- TS
- freecodecamp
- git flow start
- 백준
- javascript30
- js
- 공부할 거 넘많다~
- Next.js
- Today
- Total
다다의 개발일지 6v6
[DB] - SQL(MySQL) vs NoSQL(MongoDB) 차이점 본문
SQL과 NoSQL은 둘 다 데이터를 저장하고 관리하는 데이터베이스 시스템이다.
하지만 데이터 구조, 사용 방식, 확장성 등이 다르기 때문에 각각의 장단점이 있음
SQL (MySQL)
SQL (Structured Query Language)은 관계형 데이터베이스(RDB, Relational Database)를 다룰 때 사용함.
- MySQL, PostgreSQL, Oracle, MSSQL 등이 대표적인 SQL 데이터베이스
- 행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사
- 데이터 50만 개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하기는 어렵지만, 정형화되어 있는 만큼 데이터가 일관적이고 분석에 용이
Query Language란
쿼리 언어(Query Language)
쿼리(Query) = 데이터베이스에게 요청을 보내는 것
쿼리 언어(Query Language) = 데이터를 조회, 추가, 수정, 삭제 요청하는 명령어
▶ SQL (Structured Query Language)
SQL은 관계형 데이터베이스(MySQL, PostgreSQL 등)에서 데이터를 다룰 때 사용하는 쿼리 언어.
예제 (MySQL에서 데이터를 조회하는 SQL 쿼리)
SELECT name, age FROM users WHERE age > 20;
위 코드는 users 테이블에서 age가 20보다 큰 사람의 name과 age를 가져온다!
▶ MongoDB의 NoSQL 쿼리
NoSQL 데이터베이스(MongoDB 등)도 데이터를 조회할 때 쿼리 명령을 사용하지만, SQL과 다르게 JSON 기반 명령어를 사용한다.
예제 (MongoDB에서 데이터를 조회하는 쿼리)
db.users.find({ age: { $gt: 20 } }, { name: 1, age: 1 });
SQL과 비슷하지만, JSON 형태의 명령어를 사용한다.
✅ 특징:
✔ 데이터를 테이블(table) 형태로 저장
✔ 행(row)과 열(column) 구조로 되어 있음
✔ SQL(쿼리 언어)를 사용해 데이터를 조회/추가/수정/삭제
✔ 데이터 간 관계를 설정(Join, Foreign Key) 해서 정규화 가능
✔ 정해진 스키마(고정된 데이터 구조)가 있어야 함
▶ JOIN과 FOREIGN KEY란?
JOIN과 FOREIGN KEY란?
SQL은 여러 개의 테이블을 서로 연결해서 사용하는 특징이 있다.
🔹 FOREIGN KEY (외래키)
한 테이블이 다른 테이블의 데이터를 참조할 때 사용하는 키(컬럼)
즉, 두 테이블 간 "연결(관계)"을 만드는 역할.
📌 예제
CREATE TABLE users (
id INT PRIMARY KEY, -- users 테이블의 고유 ID
name VARCHAR(50)
);
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT, -- users 테이블의 id를 참조하는 외래키
product VARCHAR(100),
FOREIGN KEY (user_id) REFERENCES users(id)
);
여기서 orders 테이블의 user_id는 users 테이블의 id를 참조하는 FOREIGN KEY임.
즉, orders.user_id는 반드시 users.id에 있는 값만 들어갈 수 있다.
🔹 JOIN (테이블을 합치는 명령어)
두 개 이상의 테이블에서 데이터를 가져올 때 사용!
📌 예제 (사용자와 주문 정보를 합쳐서 가져오기)
SELECT users.name, orders.product
FROM users
JOIN orders ON users.id = orders.user_id;
👉 users 테이블과 orders 테이블을 user_id로 연결해서 가져오는 것!
🔹 SQL이 관계형 데이터베이스(RDB)라고 불리는 이유가 바로 이런 관계(FOREIGN KEY, JOIN)를 다루기 때문
▶ 스키마(Schema)란?
데이터베이스의 구조(형식, 규칙)를 정의한 것
스키마(Schema)란?
🔹 SQL (MySQL)의 스키마
MySQL 같은 관계형 데이터베이스는 스키마가 고정적이다
즉, 테이블의 컬럼(열)과 데이터 타입을 미리 정해야함
📌 예제 (MySQL에서 users 테이블의 스키마 정의)
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT NOT NULL
);
👉 여기서 id는 정수형, name은 50자 이하 문자열, age는 반드시 있어야 하는 정수형.
💡 스키마를 미리 정해야 하기 때문에 데이터 구조를 바꾸려면 테이블을 수정해야 함!
🔹 MySQL에서 스키마 변경이 어려운 이유
만약 새로운 컬럼이 필요하면 ALTER TABLE을 사용해서 테이블을 변경.
📌 예제: 새로운 필드 추가 (MySQL)
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
👉 모든 데이터에 영향을 주기 때문에 부담이 큼!
🔹 NoSQL (MongoDB)의 스키마
MongoDB 같은 NoSQL은 스키마가 자유로워서 새로운 필드를 자유롭게 추가 가능!
즉, 컬렉션에 넣을 데이터 구조가 고정되지 않아서, 각 문서의 필드가 다를 수도 있다.
기존 데이터에 영향을 주지 않고 새로운 데이터 구조를 저장할 수 있음.
📌 예제 (MongoDB에 다양한 구조의 데이터 저장)
db.users.insertOne({ name: "Alice", age: 25 });
db.users.insertOne({ name: "Bob", hobbies: ["reading", "coding"] });
👉 Alice는 age 필드만 있고, Bob은 hobbies 필드가 있어도 문제없다!
💡 NoSQL은 스키마를 미리 정할 필요가 없기 때문에, 데이터 구조가 자주 바뀔 때 유용하다
- 유연한 데이터 저장이 가능해서 개발 속도가 빠름
- JSON 기반이기 때문에 직관적이고 다루기 쉬움
📌 예제 (MySQL 테이블 구조)
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT,
email VARCHAR(100)
);
📌 데이터 삽입 (INSERT)
INSERT INTO users (name, age, email) VALUES ('Alice', 25, 'alice@example.com');
📌 데이터 조회 (SELECT)
SELECT * FROM users WHERE age > 20;
🔹 MySQL을 쓰는 이유
✔ JOIN, FOREIGN KEY를 이용해서 여러 테이블을 안전하게 연결 가능
✔ 데이터 중복을 최소화할 수 있음 (정규화)
✔ 트랜잭션(Transaction) 기능으로 데이터 정합성 보장 가능
✔ 데이터 간의 관계(1:N, N:M 등)가 명확할 때는 MySQL(RDBMS)이 강력
✅ MySQL을 써야 하는 경우
- 은행, 금융, 쇼핑몰(고객-주문), 병원(환자-진료기록)처럼 데이터 관계가 중요한 경우
- 데이터 무결성(Integrity)이 중요하고, 잘못된 데이터가 들어가면 안 되는 경우
- 금융, 은행, ERP 시스템 등 데이터 정합성이 중요한 경우
- 데이터 구조가 자주 바뀌지 않는 경우
데이터 정합성(Data Integrity)이란?
데이터가 정확하고 일관성 있게 유지되는 것!
데이터가 잘못된 값으로 저장되거나, 관계가 깨지는 걸 방지하는 개념이다.
SQL(MySQL)은 FOREIGN KEY, TRANSACTION(트랜잭션) 같은 기능을 통해 데이터 정합성을 보장한다
- 트랜잭션(Transaction)은 데이터베이스에서 하나의 작업 단위를 의미함.
트랜잭션은 여러 가지 작업을 하나의 묶음으로 처리해서 모두 성공하거나 모두 실패하도록 보장하는 중요한 개념임 - 은행 시스템에서 A 계좌에서 B 계좌로 송금하는 트랜잭션 예시:
- A 계좌에서 100원을 출금한다.
- B 계좌에 100원을 입금한다.
- 트랜잭션을 사용할 때의 장점:
- 데이터 무결성: 작업 중 오류가 나면 모든 작업이 취소되기 때문에 데이터가 깨지지 않음.
- 동시성 문제 해결: 여러 작업이 동시에 진행되더라도, 각 트랜잭션이 독립적으로 실행되므로 상호 간섭을 방지할 수 있음.
- 안전성 보장: 데이터베이스가 일관된 상태를 유지하도록 보장하여 안전한 데이터 변경을 할 수 있음.
- 지속성 (Durability):
- 트랜잭션이 완료되면, 모든 변경 사항은 영구적으로 데이터베이스에 반영되어야 해.
- 시스템 장애가 발생해도, 트랜잭션 완료 후의 상태는 손실되지 않음.
- 트랜잭션을 사용한 예시 (SQL에서)
혹은, 만약 오류가 발생하면:START TRANSACTION; -- 트랜잭션 시작 UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A'; -- A 계좌에서 100원 출금 UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B'; -- B 계좌에 100원 입금 COMMIT; -- 트랜잭션이 성공적으로 완료되었을 때, 변경 사항을 저장
ROLLBACK; -- 트랜잭션을 취소하고, 모든 변경 사항을 원래 상태로 돌림 - 트랜잭션이 필요한 경우
- 금융 거래: 송금, 결제 등에서 데이터의 일관성을 보장하기 위해 사용
- 데이터베이스에 여러 변경을 동시에 적용해야 할 때: 여러 테이블에 데이터를 수정해야 할 때, 일부만 수정되면 문제가 되므로 트랜잭션을 사용
📌 데이터 정합성이 깨지는 경우
예를 들어, users 테이블과 orders 테이블이 있다고 해보자.
-- users 테이블
id | name
------------
1 | Alice
2 | Bob
-- orders 테이블 (user_id가 users 테이블을 참조)
id | user_id | product
----------------------
1 | 1 | Laptop
2 | 3 | Phone <-- ❌ users 테이블에 user_id=3이 없는데 주문이 들어감!
👉 user_id = 3인 사용자가 users 테이블에 없는데 주문이 들어갔다면?
MySQL은 외래키(Foreign Key)를 통해 이런 잘못된 데이터를 막을 수 있다
-> 외래키를 사용하면 orders.user_id는 반드시 users.id에 있는 값만 들어갈 수 있다.
트랜잭션(Transaction)을 통해 여러 작업을 하나로 묶어서 처리할 수도 있다!
📌 반면, MongoDB(NoSQL)는 이런 데이터 정합성을 강하게 보장하지 않아서 orders 컬렉션에서 user_id: 3이 들어가도 오류가 나지 않는다
👉 데이터 정합성이 중요한 금융/은행 시스템에서는 MySQL 같은 SQL이 적합
👉 NoSQL은 빠른 데이터 저장이 필요하지만, 정합성이 덜 중요한 경우에 적합
NoSQL (MongoDB)
NoSQL (Not Only SQL)은 비관계형 데이터베이스로, 다양한 데이터 저장 방식을 지원.
- MongoDB, Redis, Cassandra, Firebase 등이 대표적인 NoSQL 데이터베이스.
- 데이터 하나하나 마다 같은 필드 값들을 가질 필요가 없어 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있음.
✅ 특징:
✔ 데이터를 JSON 형태의 문서(document) 로 저장
✔ 스키마(고정된 구조) 없이 유연한 데이터 저장 가능
✔ 관계를 강제하지 않고, 중첩된 데이터 저장 가능 (Embed)
✔ 수평 확장(서버 추가)하기 쉬움
✔ 대량의 데이터를 빠르게 처리할 수 있음
📌 예제 (MongoDB 문서 구조)
{
"_id": ObjectId("507f1f77bcf86cd799439011"),
"name": "Alice",
"age": 25,
"email": "alice@example.com",
"hobbies": ["reading", "coding"],
"address": { "city": "Seoul", "country": "Korea" }
}
📌 데이터 삽입 (INSERT)
db.users.insertOne({
name: "Alice",
age: 25,
email: "alice@example.com"
});
📌 데이터 조회 (FIND)
db.users.find({ age: { $gt: 20 } });
🔹 NoSQL을 쓰는 경우
✔ 관계형 데이터가 적거나, 하나의 문서(document) 안에 모든 정보를 포함할 수 있을 때
✔ 데이터를 빠르게 저장하고 읽어야 할 때 (대용량 데이터)
✔ 스키마를 유연하게 변경하고 싶을 때
👉 orders 컬렉션에 user 정보를 직접 포함해서 저장! (JOIN이 필요 없음)
👉 한 번에 데이터를 불러올 수 있어서 성능이 좋다
✅ NoSQL을 써야 하는 경우
- SNS(게시글-댓글), 실시간 데이터 처리(채팅, 로그), IoT, 빅데이터
- 관계가 복잡하지 않고, 한 문서에 데이터를 통째로 저장하는 게 효율적인 경우
- 데이터 구조가 자주 바뀌는 경우
- 수평 확장이 필요한 경우
확장성
🔹 MySQL은 수직 확장이 일반적 ( 한 대의 서버 성능을 높이는 것 (RAM, CPU 추가 등) )
MySQL 같은 관계형 데이터베이스는 JOIN, 트랜잭션 등이 필요하기 때문에 한 대의 강력한 서버에서 처리하는 경우가 많다.
✔ 한 개의 중앙 서버가 모든 데이터를 관리해야 해서 분산이 어려움!
✔ 여러 개의 서버에 나눠 저장하면 JOIN이 어렵고, 속도가 느려질 수 있음.
🔹 MongoDB는 수평 확장이 쉬움! ( 서버 여러 대를 추가해서 성능을 높이는 것 )
MongoDB는 데이터를 여러 서버에 나눠 저장(Sharding) 할 수 있다.
✔ JOIN이 필요 없고, 데이터가 독립적이라 여러 서버에 분산이 가능!
✔ 새로운 서버를 추가하는 것만으로 성능을 쉽게 높일 수 있음.
✔ 클라우드 환경에서 확장성이 뛰어남
📌 예제: Sharding(샤딩)
sh.enableSharding("myDatabase") # 데이터베이스를 샤딩 가능하게 설정
👉 이렇게 하면 여러 서버에 데이터를 나눠서 저장할 수 있다!
SQL vs NoSQL 차이점 비교
| SQL (MySQL) | NoSQL (MongoDB) | |
| 데이터 구조 | 테이블 (행과 열) | 문서(JSON) |
| 스키마(구조) | 고정된 스키마 필요 | 유연한 구조 |
| 확장성 | 수직 확장 (서버 성능 업그레이드) | 수평 확장 (서버 여러 개 추가) |
| 관계(Relationships) | 여러 테이블을 연결 (Join) | 중첩된 데이터 저장 가능 (Embed) |
| 속도 | 복잡한 쿼리 처리에 강함 | 빠른 데이터 읽기/쓰기 처리 |
| 적용 분야 | 금융, ERP, 전자상거래 등 | 빅데이터, 실시간 처리, 로그, SNS 등 |
| 데이터 정합성 | 강력한 정합성 보장 (Foreign Key, Transaction) | 정합성이 약함 (빠른 성능 중심) |
👉 SQL(MySQL) = 관계형 데이터, 데이터 정합성이 중요한 경우
👉 NoSQL(MongoDB) = 대량의 데이터를 빠르게 저장하고, 유연한 구조가 필요한 경우