데이터베이스 | Database
내가 볼려고 작성한 CS 공부.
⚙️ 데이터베이스
✅ 1. 관계형 DB & NoSQL
1.1 관계형 데이터베이스 (Relational DB)
관계형 데이터베이스는 테이블(표) 형태로 데이터를 저장하고,
열(Column) 은 속성, 행(Row) 은 데이터 레코드를 의미한다.
주요 특징
| 항목 | 설명 |
|---|---|
| 데이터 구조 | 테이블 기반 (스키마 고정) |
| 제약 조건 | 데이터 무결성 강함 (PK, FK 등) |
| 언어 | SQL 사용 |
| 트랜잭션 | 강력한 ACID 보장 |
| 예시 | MySQL, PostgreSQL, Oracle, SQL Server |
스키마 기반으로 엄격하게 구조화되어 있어
정형 데이터 처리와 복잡한 쿼리에 매우 강력하다.
1.2 NoSQL (Not Only SQL)
NoSQL은 비정형 또는 유연한 구조의 데이터를 저장하기 위한 DB 유형이다.
RDB의 한계를 보완하고, 확장성과 유연성을 목표로 한다.
주요 유형
| 유형 | 설명 | 예시 |
|---|---|---|
| 문서(Document) | JSON 기반 문서 저장 | MongoDB |
| 키-값(Key-Value) | Key와 Value 쌍 저장 | Redis, DynamoDB |
| 그래프(Graph) | 노드-간선 구조 | Neo4j |
| 컬럼(Column) | 열 단위 저장 | Cassandra, HBase |
스키마 없이 자유롭게 데이터를 넣을 수 있어,
빅데이터, 실시간 처리, 빠른 개발에 적합하다.
1.3 관계형 DB vs NoSQL
| 항목 | 관계형 DB | NoSQL |
|---|---|---|
| 구조 | 테이블, 정형 | 유연, 비정형 |
| 확장성 | 수직 확장 (스케일 업) | 수평 확장 (스케일 아웃) |
| 스키마 | 고정 | 유동적 |
| 트랜잭션 | ACID 보장 | BASE 지향 (일관성 ↓, 가용성 ↑) |
| 쿼리 | SQL | 각 DB별 방식 다름 |
| 사용 예 | 금융, ERP, 정형 분석 | 실시간 로그, SNS, 캐시 등 |
1.4 언제 어떤 걸 쓸까?
- 관계형 DB가 유리한 경우
- 데이터 구조가 명확함
- 복잡한 JOIN, 트랜잭션 필요
- 일관성과 정합성이 중요한 시스템 (예: 은행, 회계)
- NoSQL이 유리한 경우
- 데이터 스키마가 자주 바뀜
- 대규모 분산 환경 필요
- 속도, 유연성이 더 중요함 (예: SNS, IoT 로그)
실제 서비스에서는 RDB와 NoSQL을 혼용하는 경우도 많다.
✅ 2. SQL 기초 및 JOIN
2.1 SQL이란?
SQL(Structured Query Language)은 데이터베이스에서 데이터를 조회, 삽입, 수정, 삭제하기 위한 언어다.
관계형 데이터베이스에서는 반드시 사용하는 표준 언어다.
2.2 SQL 기본 문법
조회: SELECT
1
SELECT 이름, 나이 FROM 사용자 WHERE 나이 >= 20;
- 원하는 컬럼을 조회
- 조건에 따라 필터링 가능
삽입: INSERT
1
INSERT INTO 사용자 (이름, 나이) VALUES ('철수', 25);
수정: UPDATE
1
UPDATE 사용자 SET 나이 = 26 WHERE 이름 = '철수';
삭제: DELETE
1
DELETE FROM 사용자 WHERE 나이 < 20;
2.3 조건문 & 정렬
| 문법 | 설명 | 예시 |
|---|---|---|
| WHERE | 조건문 | WHERE 성별 = ‘M’ |
| ORDER BY | 정렬 | ORDER BY 나이 DESC |
| LIMIT | 결과 제한 | LIMIT 10 |
| LIKE | 문자열 검색 | WHERE 이름 LIKE ‘김%’ |
2.4 집계 함수
| 함수 | 설명 |
|---|---|
| COUNT() | 행 개수 |
| SUM() | 합계 |
| AVG() | 평균 |
| MAX() / MIN() | 최댓값 / 최솟값 |
1
SELECT COUNT(*) FROM 사용자 WHERE 성별 = 'F';
2.5 GROUP BY & HAVING
같은 값을 기준으로 묶어서 집계할 때 사용
1
2
3
4
SELECT 성별, AVG(나이)
FROM 사용자
GROUP BY 성별
HAVING AVG(나이) >= 25;
2.6 JOIN이란?
JOIN은 여러 테이블에 흩어진 데이터를 합쳐서 조회할 수 있도록 해준다.
일반적으로 외래 키(FK)를 통해 연결된 테이블을 조인한다.
2.7 JOIN 종류
| 종류 | 설명 | 포함되는 행 |
|---|---|---|
| INNER JOIN | 양쪽 모두 일치하는 데이터만 | 교집합 |
| LEFT JOIN | 왼쪽 테이블은 모두, 오른쪽은 일치하는 것만 | 왼쪽 중심 |
| RIGHT JOIN | 오른쪽 테이블은 모두 | 오른쪽 중심 |
| FULL OUTER JOIN | 양쪽 모두 포함 | 합집합 (일부 DB에서만 지원) |
INNER JOIN 예시
1
2
3
SELECT 사용자.이름, 주문.상품명
FROM 사용자
INNER JOIN 주문 ON 사용자.id = 주문.사용자_id;
LEFT JOIN 예시
1
2
3
SELECT 사용자.이름, 주문.상품명
FROM 사용자
LEFT JOIN 주문 ON 사용자.id = 주문.사용자_id;
주문이 없는 사용자도 모두 포함됨
2.8 실전 JOIN 예시
두 테이블:
- 사용자(id, 이름)
- 주문(id, 사용자_id, 상품명)
→ 사용자별로 주문 내역을 보고 싶다
1
2
3
SELECT u.이름, o.상품명
FROM 사용자 u
JOIN 주문 o ON u.id = o.사용자_id;
실무에서는 JOIN을 잘 활용하면 정규화된 테이블도 손쉽게 분석할 수 있다.
✅ 3. 정규화 & 비정규화
3.1 정규화(Normalization)란?
정규화는 데이터의 중복을 제거하고, 논리적으로 구조화하는 과정이다.
데이터 무결성을 높이고 저장 공간을 효율화하기 위해 수행된다.
테이블을 잘게 나누고, 관계를 통해 재구성하는 방식
3.2 정규화의 목적
| 목적 | 설명 |
|---|---|
| 중복 제거 | 동일한 정보 반복 입력 방지 |
| 데이터 무결성 유지 | 이상현상(삽입·삭제·갱신 이상) 제거 |
| 변경 용이성 향상 | 변경 시 연쇄 수정 줄임 |
| 유지 보수 편리 | 구조 명확, 설계 논리적 |
3.3 정규형 단계 요약
| 단계 | 내용 | 조건 |
|---|---|---|
| 제1정규형(1NF) | 컬럼은 원자값만 저장 | 중첩 데이터 금지 |
| 제2정규형(2NF) | 부분적 종속 제거 | 기본키 전체에 종속 |
| 제3정규형(3NF) | 이행적 종속 제거 | 기본키가 아닌 컬럼끼리 종속 금지 |
대부분의 실무 DB는 3NF 수준에서 정규화된 구조를 사용함
3.4 이상현상(Anomaly)이란?
테이블이 비정규화되어 있으면 다음과 같은 문제가 발생할 수 있다.
| 이상 | 설명 |
|---|---|
| 삽입 이상 | 일부 정보만으로는 입력이 불가능 |
| 삭제 이상 | 하나의 정보 삭제가 관련된 다른 정보까지 제거 |
| 갱신 이상 | 중복된 데이터 일괄 수정 어려움 |
3.5 비정규화(Denormalization)란?
비정규화는 성능 향상을 위해 정규화된 테이블을 일부 통합하거나
중복 데이터를 허용하는 작업이다.
SELECT 성능을 높이고 JOIN 횟수를 줄이기 위해 사용된다.
3.6 정규화 vs 비정규화 비교
| 항목 | 정규화 | 비정규화 |
|---|---|---|
| 목적 | 데이터 일관성, 무결성 | 성능 향상, 쿼리 단순화 |
| 테이블 수 | 많음 (세분화) | 적음 (통합) |
| 중복 | 제거 | 허용 |
| 속도 | 느릴 수 있음 (JOIN 많음) | 빠름 (조회 최적화) |
| 관리 | 변경 용이 | 일부 중복으로 인한 관리 어려움 |
3.7 실무에서의 적용
- 정규화 우선, 성능 병목이 생길 경우에만 비정규화 적용
- 조회 성능이 중요한 보고서/대시보드용 테이블은 비정규화 구조 많이 씀
- RDB 설계 시: 정규화 + 필요 시 인덱스/캐시/뷰 등과 병행
✅ 4. 인덱스, 트랜잭션, ACID
4.1 인덱스(Index)
인덱스는 데이터를 빠르게 찾기 위해 사용하는 구조다.
책의 목차처럼, 원하는 데이터를 빠르게 찾을 수 있게 도와준다.
4.1.1 특징
| 항목 | 설명 |
|---|---|
| 목적 | 검색 속도 향상 (조회 최적화) |
| 기본 구조 | B-Tree, Hash 등 |
| 생성 대상 | WHERE, JOIN, ORDER BY에 자주 사용되는 컬럼 |
| 단점 | INSERT/UPDATE/DELETE 시 인덱스도 함께 수정 → 오버헤드 발생 |
SELECT는 빨라지지만, DML(데이터 조작)은 느려질 수 있음
4.1.2 인덱스 예시
1
SELECT * FROM 사용자 WHERE 이메일 = 'abc@ex.com';
→ 이메일 컬럼에 인덱스가 있다면 훨씬 빠르게 조회됨
4.2 트랜잭션(Transaction)
트랜잭션은 데이터베이스에서 하나의 논리적 작업 단위다.
모든 작업이 전부 성공하거나, 전부 실패해야 함 (ALL or NOTHING)
4.2.1 예시
- 계좌 A → B로 이체할 때
- A 계좌에서 출금
- B 계좌에 입금
둘 중 하나라도 실패하면, 전체 작업은 취소되어야 한다.
4.2.2 명령어
| 명령 | 설명 |
|---|---|
| BEGIN / START TRANSACTION | 트랜잭션 시작 |
| COMMIT | 트랜잭션 확정 |
| ROLLBACK | 오류 시 되돌리기 |
4.3 ACID란?
ACID는 트랜잭션이 만족해야 할 4가지 속성을 의미한다.
| 속성 | 설명 |
|---|---|
| A - 원자성(Atomicity) | 모두 실행되거나 모두 실행되지 않음 |
| C - 일관성(Consistency) | 정합성 있는 상태만 유지 |
| I - 고립성(Isolation) | 동시에 실행되는 트랜잭션 간 간섭 없음 |
| D - 지속성(Durability) | 성공된 트랜잭션 결과는 영구 반영됨 |
이 4가지를 만족해야 신뢰할 수 있는 DB 처리라 할 수 있다.
4.4 인덱스와 트랜잭션의 관계
- 인덱스는 조회 속도 향상에 유리
- 트랜잭션은 정합성/무결성 보장이 목적
- 실무에서는 읽기는 빠르게, 쓰기는 안정적으로 → 인덱스 + 트랜잭션 적절히 조합
✅ 5. 락, 격리 수준, 데드락
5.1 락(Lock)
락은 여러 트랜잭션이 동시에 같은 데이터에 접근할 때, 충돌을 방지하기 위한 장치다.
| 락 종류 | 설명 |
|---|---|
| 공유 락(Shared Lock) | 읽기만 허용 (다른 읽기 가능, 쓰기는 불가) |
| 배타 락(Exclusive Lock) | 읽기/쓰기 모두 차단 (오직 1개 트랜잭션만 접근 가능) |
공유 락은 SELECT 시 주로 사용,
배타 락은 UPDATE/DELETE 같은 쓰기 작업에서 사용됨
예시
- A 트랜잭션이 테이블을 읽고 있을 때 → B도 읽기는 가능
- A가 테이블을 수정하고 있다면 → B는 읽기/쓰기 모두 대기
5.2 격리 수준 (Isolation Level)
여러 트랜잭션이 동시에 실행될 때 어느 정도 서로 영향을 허용할지를 설정하는 것
격리 수준이 낮을수록 성능은 좋지만 정합성이 떨어질 수 있다.
| 수준 | 허용 현상 | 설명 |
|---|---|---|
| READ UNCOMMITTED | Dirty Read 허용 | 커밋되지 않은 데이터 읽기 허용 |
| READ COMMITTED | Dirty Read 방지 | 커밋된 데이터만 읽음 (기본값: Oracle, MSSQL) |
| REPEATABLE READ | Non-repeatable Read 방지 | 같은 쿼리에서 항상 동일한 결과 보장 |
| SERIALIZABLE | 모든 이상현상 차단 | 완전한 격리 (가장 안전하지만 느림) |
발생할 수 있는 문제
| 현상 | 설명 |
|---|---|
| Dirty Read | 다른 트랜잭션이 아직 커밋하지 않은 값을 읽음 |
| Non-repeatable Read | 같은 쿼리를 반복해도 값이 바뀜 |
| Phantom Read | 조건에 맞는 행 개수가 바뀜 (INSERT/DELETE로 인해) |
5.3 데드락 (Deadlock)
두 개 이상의 트랜잭션이 서로가 가진 락을 기다리며 영원히 멈추는 상태
예시
- 트랜잭션 A가 레코드 1을 락 걸고 → 레코드 2 대기
- 트랜잭션 B가 레코드 2를 락 걸고 → 레코드 1 대기
→ 둘 다 서로가 풀어주길 기다리며 영원히 대기
5.4 데드락 방지 방법
| 방법 | 설명 |
|---|---|
| 트랜잭션 순서 통일 | 항상 동일한 순서로 자원 요청 |
| 타임아웃 설정 | 일정 시간 대기 후 자동 취소 |
| 최소 단위 락 사용 | 락 범위를 작게 설정 (Row-level Lock 등) |
RDBMS는 자체적으로 데드락을 감지해서
하나의 트랜잭션을 강제로 종료시키는 기능도 있다.
✅ 6. 샤딩, 복제, 분산 DB 구조
6.1 샤딩 (Sharding)
샤딩은 하나의 테이블(또는 DB)을 여러 개로 분할해서,
데이터를 나누어 저장하는 수평 확장 기법이다.
특징
| 항목 | 설명 |
|---|---|
| 분할 기준 | 사용자 ID, 지역, 해시 등으로 분산 |
| 목적 | 데이터 양이 많아질 때 성능 확보 |
| 이점 | INSERT/SELECT 속도 향상, 부하 분산 |
| 단점 | JOIN, 정렬 등 복잡한 쿼리는 불리함 |
예시
- 사용자 테이블을 100만 단위로 나눔:
- user_1, user_2, user_3 …
- 또는 사용자 ID의 해시값 기준으로 분산 저장
6.2 복제 (Replication)
복제는 하나의 DB 데이터를 다른 DB로 동일하게 복사하는 구조다.
읽기 부하 분산이나 백업/재해 복구 용도로 사용된다.
| 구성 | 설명 |
|---|---|
| 마스터(Master) | 쓰기 전용, 데이터의 원본 |
| 슬레이브(Slave) | 읽기 전용, 마스터를 복제 |
복제 방식
| 방식 | 설명 |
|---|---|
| 비동기 복제 | 마스터 → 슬레이브로 복제, 약간의 지연 있음 |
| 동기 복제 | 마스터와 슬레이브가 항상 동일하게 유지 (느림) |
실무에서는 보통 비동기 복제 + 읽기 전용 슬레이브 다수를 구성함
6.3 분산 DB (Distributed DB)
분산 DB는 여러 DB 시스템이 네트워크로 연결되어, 하나의 논리적 DB처럼 작동하는 구조다.
| 특징 | 설명 |
|---|---|
| 위치 | 물리적으로 떨어진 서버에 데이터 분산 |
| 특징 | 위치 투명성, 장애 허용성, 확장성 |
| 예시 | Google Spanner, Amazon Aurora, CockroachDB 등 |
분산 DB는 샤딩 + 복제 + 일관성 프로토콜 등을 함께 고려해야 한다.
6.4 비교 정리
| 항목 | 샤딩 | 복제 | 분산 DB |
|---|---|---|---|
| 목적 | 데이터 나누기 | 복사해서 읽기 분산 | 네트워크 기반 DB 통합 |
| 확장 방식 | 수평 분할 | 수직 복제 | 수평+수직 가능 |
| 쓰기 처리 | 각 샤드에서 처리 | 마스터만 처리 | 노드 분산 처리 가능 |
| 읽기 처리 | 샤드마다 별도 | 슬레이브에서 처리 | 글로벌 쿼리 가능 |
| 장애 대응 | 특정 샤드에만 영향 | 슬레이브로 대체 가능 | 노드 간 이중화 필수 |
6.5 실무 적용 방식
- 샤딩: 데이터 양이 많을 때 필수 (사용자 단위, 지역 단위 등)
- 복제: 읽기 처리량 증가 시 (읽기 많은 서비스)
- 분산 DB: 글로벌 서비스, 멀티 리전 요구 시 (복잡하지만 강력)