데이터베이스 심화 면접 완벽 가이드: 마이그레이션, 클러스터링 vs 파티셔닝, DELETE/TRUNCATE/DROP, In-Memory DB까지

데이터베이스 심화 면접 완벽 가이드: 마이그레이션, 클러스터링 vs 파티셔닝, DELETE/TRUNCATE/DROP, In-Memory DB까지

“DELETE와 TRUNCATE의 차이는?”, “DB 마이그레이션 시 고려사항은?”, “클러스터링과 파티셔닝의 차이는?” — 데이터베이스 심화 주제는 신입 면접에서도 자주 등장하며, 흩어져 있는 개념을 하나로 정리해두면 빠르게 답변할 수 있다.


1. DELETE vs TRUNCATE vs DROP

1.1 세 가지 비교

1
2
3
4
5
6
7
8
9
┌─────────────────────────────────────────────────────────────────────┐
│             DELETE vs TRUNCATE vs DROP                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  DELETE   : 데이터만 행 단위로 삭제 (조건 지정 가능)               │
│  TRUNCATE : 데이터 전체 삭제 (테이블 구조 유지)                    │
│  DROP     : 테이블 자체를 삭제 (구조 + 데이터 모두)               │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.2 상세 비교표

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
29
┌─────────────────────────────────────────────────────────────────────┐
│          DELETE vs TRUNCATE vs DROP 비교표                            │
├──────────────┬──────────────┬──────────────────┬─────────────────────┤
│ 항목         │ DELETE       │ TRUNCATE         │ DROP                │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 분류         │ DML          │ DDL              │ DDL                 │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 삭제 대상    │ 행 (조건부)  │ 전체 행          │ 테이블 자체         │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ WHERE 절     │ 사용 가능    │ 사용 불가        │ 해당 없음           │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 롤백         │ 가능         │ 불가 (자동 커밋) │ 불가 (자동 커밋)    │
│ (트랜잭션)   │ (COMMIT 전)  │                  │                     │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 속도         │ 느림         │ 빠름             │ 빠름                │
│              │ (행 단위 삭제│ (테이블 초기화)  │                     │
│              │ + 로그 기록) │                  │                     │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 로그         │ 행마다 기록  │ 최소 로그        │ 최소 로그           │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ AUTO_        │ 유지         │ 초기화 (1부터)   │ 해당 없음           │
│ INCREMENT    │              │                  │                     │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 테이블 구조  │ 유지         │ 유지             │ 삭제                │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 트리거       │ 실행됨       │ 실행 안 됨       │ 해당 없음           │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 디스크 공간  │ 즉시 반환 X  │ 즉시 반환        │ 즉시 반환           │
└──────────────┴──────────────┴──────────────────┴─────────────────────┘

1.3 사용 시나리오

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────────────┐
│                    언제 무엇을 쓰는가                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  DELETE                                                             │
│  • 특정 조건의 데이터만 삭제할 때                                   │
│    DELETE FROM orders WHERE status = 'CANCELLED';                   │
│  • 삭제 후 롤백이 필요할 수 있을 때                                 │
│  • 삭제 트리거가 실행되어야 할 때                                   │
│                                                                     │
│  TRUNCATE                                                           │
│  • 테이블의 모든 데이터를 빠르게 비울 때                            │
│    TRUNCATE TABLE temp_logs;                                        │
│  • 테스트 환경 초기화                                               │
│  • AUTO_INCREMENT를 1부터 다시 시작하고 싶을 때                     │
│                                                                     │
│  DROP                                                               │
│  • 테이블 자체가 더 이상 필요 없을 때                               │
│    DROP TABLE IF EXISTS old_backup;                                 │
│  • 스키마 재설계 시                                                 │
│                                                                     │
│  ⚠️ TRUNCATE와 DROP은 롤백 불가 → 운영 DB에서 극도로 주의!         │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2. 클러스터링 vs 파티셔닝 vs 샤딩

2.1 개념 비교

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
┌─────────────────────────────────────────────────────────────────────┐
│           클러스터링 vs 파티셔닝 vs 샤딩                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  [클러스터링 (Clustering)]                                          │
│  = 여러 DB 서버를 하나의 그룹으로 묶어 동작                        │
│  = 목적: 고가용성 (HA) + 부하 분산                                 │
│                                                                     │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                            │
│  │  DB #1  │  │  DB #2  │  │  DB #3  │                            │
│  │ (Master)│  │(Replica)│  │(Replica)│                             │
│  └────┬────┘  └────┬────┘  └────┬────┘                            │
│       └─────── 동기화 ─────────┘                                    │
│                                                                     │
│  → 같은 데이터를 여러 서버에 복제                                   │
│  → 한 서버 장애 시 다른 서버가 대체                                 │
│                                                                     │
│  ───────────────────────────────────────────────────                │
│                                                                     │
│  [파티셔닝 (Partitioning)]                                          │
│  = 하나의 큰 테이블을 여러 조각으로 분할 (같은 DB 내)              │
│  = 목적: 쿼리 성능 향상                                             │
│                                                                     │
│  ┌────────────────── DB 서버 (1대) ──────────────────┐             │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐          │             │
│  │  │ orders   │ │ orders   │ │ orders   │          │             │
│  │  │ 2024년   │ │ 2025년   │ │ 2026년   │          │             │
│  │  └──────────┘ └──────────┘ └──────────┘          │             │
│  └───────────────────────────────────────────────────┘             │
│                                                                     │
│  → 논리적으로는 하나의 테이블, 물리적으로 분할                      │
│  → 특정 파티션만 스캔 → 성능 향상 (Partition Pruning)              │
│                                                                     │
│  ───────────────────────────────────────────────────                │
│                                                                     │
│  [샤딩 (Sharding)]                                                  │
│  = 데이터를 여러 DB 서버에 분산 저장                                │
│  = 목적: 수평 확장 (Scale-Out)                                      │
│                                                                     │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                         │
│  │  Shard 1 │  │  Shard 2 │  │  Shard 3 │                         │
│  │ 유저 1~  │  │ 유저     │  │ 유저     │                         │
│  │   100만  │  │ 100~200만│  │ 200~300만│                         │
│  └──────────┘  └──────────┘  └──────────┘                         │
│  (서버 A)       (서버 B)       (서버 C)                             │
│                                                                     │
│  → 각 서버가 데이터의 일부만 담당                                   │
│  → 서버 추가로 용량/성능 선형 증가                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2.2 비교표

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────┐
│        클러스터링 vs 파티셔닝 vs 샤딩 비교                           │
├──────────────┬──────────────┬──────────────────┬─────────────────────┤
│ 항목         │ 클러스터링   │ 파티셔닝         │ 샤딩                │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 핵심 목적    │ 고가용성     │ 쿼리 성능        │ 수평 확장           │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 데이터 분포  │ 동일 데이터  │ 분할 (같은 서버) │ 분할 (다른 서버)    │
│              │ 복제         │                  │                     │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 서버 수      │ 여러 대      │ 1대              │ 여러 대             │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 장애 대응    │ 자동 Failover│ 해당 없음        │ 샤드별 독립         │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 구현 복잡도  │ 중간         │ 낮음             │ 높음                │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ Cross-Join   │ 가능         │ 가능             │ 어려움 (분산 조인)  │
├──────────────┼──────────────┼──────────────────┼─────────────────────┤
│ 예시         │ MySQL InnoDB │ RANGE, HASH,     │ Vitess, ProxySQL,   │
│              │ Cluster      │ LIST 파티션      │ 애플리케이션 샤딩   │
└──────────────┴──────────────┴──────────────────┴─────────────────────┘

2.3 파티셔닝 유형

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────┐
│                  파티셔닝 유형                                        │
├──────────────────────┬──────────────────────────────────────────────┤
│ 유형                 │ 설명                                         │
├──────────────────────┼──────────────────────────────────────────────┤
│ Range Partitioning   │ 범위 기준 분할                               │
│                      │ 예: 날짜별 (2024년, 2025년, 2026년)         │
│                      │ → 시계열 데이터에 적합                       │
├──────────────────────┼──────────────────────────────────────────────┤
│ Hash Partitioning    │ 해시 함수 결과로 분할                        │
│                      │ 예: user_id % 4                              │
│                      │ → 균등 분배에 적합                           │
├──────────────────────┼──────────────────────────────────────────────┤
│ List Partitioning    │ 특정 값 목록으로 분할                        │
│                      │ 예: region IN ('서울', '부산')              │
│                      │ → 카테고리성 데이터에 적합                   │
├──────────────────────┼──────────────────────────────────────────────┤
│ Vertical             │ 컬럼 기준 분할                               │
│ Partitioning         │ 자주 쓰는 컬럼 / 안 쓰는 컬럼 분리         │
│                      │ → BLOB, TEXT 같은 대용량 컬럼 분리          │
└──────────────────────┴──────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- Range Partitioning 예시 (MySQL)
CREATE TABLE orders (
    id BIGINT NOT NULL,
    order_date DATE NOT NULL,
    amount DECIMAL(10,2),
    PRIMARY KEY (id, order_date)
) PARTITION BY RANGE (YEAR(order_date)) (
    PARTITION p2024 VALUES LESS THAN (2025),
    PARTITION p2025 VALUES LESS THAN (2026),
    PARTITION p2026 VALUES LESS THAN (2027),
    PARTITION pmax  VALUES LESS THAN MAXVALUE
);

-- 2026년 주문만 조회 → p2026 파티션만 스캔 (Partition Pruning)
SELECT * FROM orders WHERE order_date BETWEEN '2026-01-01' AND '2026-12-31';

3. 동적 쿼리 vs 정적 쿼리

3.1 개념 비교

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
29
30
┌─────────────────────────────────────────────────────────────────────┐
│              동적 쿼리 vs 정적 쿼리                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  [정적 쿼리 (Static Query)]                                        │
│  = SQL 구조가 미리 확정되어 변하지 않는 쿼리                       │
│                                                                     │
│  SELECT * FROM member WHERE id = ?                                  │
│                                                                     │
│  • 파라미터만 바뀜 (SQL 구조는 고정)                                │
│  • Prepared Statement로 실행                                        │
│  • 실행 계획 재사용 가능 → 성능 좋음                                │
│  • SQL Injection 방지                                               │
│                                                                     │
│  ──────────────────────────────────────────────────                 │
│                                                                     │
│  [동적 쿼리 (Dynamic Query)]                                       │
│  = 조건에 따라 SQL 구조 자체가 변하는 쿼리                         │
│                                                                     │
│  SELECT * FROM member                                               │
│  WHERE 1=1                                                          │
│    AND name = ?        ← 이름 검색 시만 추가                       │
│    AND status IN (?)   ← 상태 필터 시만 추가                       │
│  ORDER BY created_at   ← 정렬 조건도 변경 가능                     │
│                                                                     │
│  • WHERE 절, JOIN, ORDER BY 등이 조건부로 변경됨                   │
│  • 검색 조건이 다양한 화면에서 필수                                 │
│  • 문자열 연결 시 SQL Injection 위험 → 반드시 안전한 방식 사용     │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3.2 동적 쿼리 구현 방식 비교

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────┐
│             동적 쿼리 구현 방식 비교                                  │
├──────────────────┬──────────────────────────────────────────────────┤
│ 방식             │ 특징                                             │
├──────────────────┼──────────────────────────────────────────────────┤
│ MyBatis          │ XML <if>, <choose>, <where>, <foreach>          │
│ (XML 태그)       │ 가독성 좋음, SQL 직접 제어                      │
├──────────────────┼──────────────────────────────────────────────────┤
│ JPA Criteria API │ Java 코드로 쿼리 빌드                           │
│                  │ 타입 안전하지만 가독성 나쁨                      │
├──────────────────┼──────────────────────────────────────────────────┤
│ QueryDSL         │ 타입 안전 + 가독성 좋음                         │
│                  │ BooleanBuilder, BooleanExpression               │
│                  │ 현재 JPA 동적 쿼리의 사실상 표준                 │
├──────────────────┼──────────────────────────────────────────────────┤
│ 문자열 연결      │ "SELECT ... " + condition                       │
│ (StringBuilder)  │ ❌ SQL Injection 위험 → 절대 사용 금지          │
├──────────────────┼──────────────────────────────────────────────────┤
│ Spring JDBC      │ NamedParameterJdbcTemplate                      │
│                  │ 조건부 SQL 빌드 가능하나 번거로움               │
└──────────────────┴──────────────────────────────────────────────────┘

3.3 Prepared Statement와 SQL Injection 방지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────────────┐
│           Prepared Statement의 중요성                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  [위험한 방식 - 문자열 연결]                                        │
│  String sql = "SELECT * FROM member WHERE name = '" + input + "'"; │
│                                                                     │
│  input = "'; DROP TABLE member; --"                                 │
│  → SELECT * FROM member WHERE name = '';                            │
│    DROP TABLE member; --'                                           │
│  → 테이블 삭제!!                                                    │
│                                                                     │
│  [안전한 방식 - Prepared Statement]                                 │
│  String sql = "SELECT * FROM member WHERE name = ?";               │
│  pstmt.setString(1, input);                                         │
│                                                                     │
│  → 파라미터가 SQL 구문이 아닌 값으로 처리됨                        │
│  → SQL Injection 불가                                               │
│                                                                     │
│  ※ JPA, MyBatis 모두 내부적으로 Prepared Statement 사용             │
│    → #{param} (MyBatis), :param (JPQL) = 안전                      │
│    → ${param} (MyBatis) = 위험! (문자열 치환)                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4. DB 마이그레이션

4.1 마이그레이션이란

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────────────┐
│                   DB 마이그레이션 개념                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  DB 마이그레이션 = 스키마 또는 데이터를 변경하는 과정               │
│                                                                     │
│  종류:                                                              │
│  1. 스키마 마이그레이션: 테이블 구조 변경                           │
│     → 컬럼 추가/삭제, 타입 변경, 인덱스 추가                       │
│                                                                     │
│  2. 데이터 마이그레이션: 데이터 이동/변환                           │
│     → MySQL → PostgreSQL 전환                                      │
│     → 레거시 데이터 정제                                            │
│                                                                     │
│  3. DB 플랫폼 마이그레이션: DB 엔진 자체 교체                      │
│     → On-Premise → Cloud RDS                                       │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4.2 마이그레이션 고려사항

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
┌─────────────────────────────────────────────────────────────────────┐
│              DB 마이그레이션 고려사항                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ① 하위 호환성 (Backward Compatibility)                             │
│     • 이전 버전 애플리케이션이 새 스키마에서도 동작해야 함          │
│     • 컬럼 삭제보다 추가가 안전                                     │
│     • NOT NULL 컬럼 추가 시 DEFAULT 값 필수                         │
│                                                                     │
│  ② 무중단 마이그레이션                                              │
│     • ALTER TABLE은 대용량 테이블에서 락 발생 가능                  │
│     • pt-online-schema-change (Percona) 등 온라인 DDL 도구 사용     │
│     • 확장-축소 전략: 추가 → 배포 → 삭제 (3단계)                   │
│                                                                     │
│  ③ 롤백 계획                                                       │
│     • 마이그레이션 실패 시 되돌릴 수 있어야 함                     │
│     • Flyway: V1__init.sql (버전 관리)                              │
│     • 데이터 백업 필수                                               │
│                                                                     │
│  ④ 데이터 정합성 검증                                               │
│     • 마이그레이션 전후 데이터 건수, 합계 등 검증                   │
│     • 체크섬 비교                                                    │
│                                                                     │
│  ⑤ 성능 영향                                                       │
│     • 피크 시간 피해서 실행                                         │
│     • 대용량 데이터 이동 시 배치 처리 (한 번에 전체 X)             │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4.3 마이그레이션 도구

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌─────────────────────────────────────────────────────────────────────┐
│              Flyway vs Liquibase                                     │
├──────────────────┬──────────────────────┬────────────────────────────┤
│ 항목             │ Flyway               │ Liquibase                  │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 스크립트 형식    │ SQL 파일             │ XML/YAML/JSON/SQL          │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 버전 관리        │ V1__name.sql         │ changelog 파일             │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 롤백             │ 유료 버전만          │ 무료로 지원                │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 학습 곡선        │ 낮음 (SQL만 알면)    │ 보통                       │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ Spring Boot 연동 │ spring.flyway.*      │ spring.liquibase.*         │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 추천 상황        │ 단순, SQL 중심       │ 복잡한 롤백 필요 시        │
└──────────────────┴──────────────────────┴────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
# Flyway 마이그레이션 파일 구조
resources/
└── db/migration/
    ├── V1__create_member_table.sql
    ├── V2__add_email_column.sql
    ├── V3__create_order_table.sql
    └── V4__add_index_on_email.sql

# 규칙: V{버전}__{설명}.sql
# → 버전 순서대로 자동 실행, 이미 실행된 버전은 스킵

5. In-Memory Database

5.1 개념과 특징

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌─────────────────────────────────────────────────────────────────────┐
│                  In-Memory Database                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  In-Memory DB = 데이터를 디스크가 아닌 메모리(RAM)에 저장           │
│                                                                     │
│  [디스크 기반 DB]                                                   │
│  애플리케이션 → 디스크 I/O → 데이터 읽기 (느림)                    │
│                                                                     │
│  [In-Memory DB]                                                     │
│  애플리케이션 → 메모리 직접 접근 → 데이터 읽기 (매우 빠름)         │
│                                                                     │
│  특징:                                                              │
│  • 읽기/쓰기 속도: 마이크로초 단위 (디스크 DB의 10~100배)          │
│  • 전원 꺼지면 데이터 소실 (별도 영속화 필요)                      │
│  • 메모리 용량에 의한 저장 한계                                     │
│  • 비용이 디스크보다 높음                                           │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 대표 In-Memory DB

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
┌─────────────────────────────────────────────────────────────────────┐
│              In-Memory DB 종류별 비교                                 │
├──────────────────┬──────────────────────────────────────────────────┤
│ DB               │ 특징                                             │
├──────────────────┼──────────────────────────────────────────────────┤
│ Redis            │ Key-Value 기반, 다양한 자료구조                  │
│                  │ 캐시, 세션, 분산 락, 랭킹 등                    │
│                  │ RDB/AOF로 영속화 가능                            │
│                  │ 운영 환경의 보조 저장소로 가장 널리 사용         │
├──────────────────┼──────────────────────────────────────────────────┤
│ H2               │ Java 기반 경량 RDBMS                             │
│                  │ 임베디드 모드 + 인메모리 모드 지원               │
│                  │ 테스트/개발 환경에서 주로 사용                   │
│                  │ Spring Boot 기본 테스트 DB                       │
├──────────────────┼──────────────────────────────────────────────────┤
│ Memcached        │ 순수 캐시 전용 (영속화 없음)                    │
│                  │ 단순 Key-Value, 멀티스레드                       │
│                  │ Redis보다 단순하지만 캐시 성능은 우수            │
├──────────────────┼──────────────────────────────────────────────────┤
│ SQLite           │ 파일 기반이지만 인메모리 모드 가능               │
│ (in-memory mode) │ :memory: 로 사용, 임베디드 테스트용             │
├──────────────────┼──────────────────────────────────────────────────┤
│ Amazon           │ AWS 관리형 Redis/Memcached                       │
│ ElastiCache      │ 클라우드 환경에서 인메모리 캐시                  │
└──────────────────┴──────────────────────────────────────────────────┘

5.3 Redis vs Memcached

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────────────────────────────────┐
│               Redis vs Memcached                                     │
├──────────────────┬──────────────────────┬────────────────────────────┤
│ 항목             │ Redis                │ Memcached                  │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 자료구조         │ String, List, Set,   │ String만                   │
│                  │ Hash, Sorted Set 등  │                            │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 영속화           │ RDB + AOF 지원       │ 없음                       │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 클러스터         │ Redis Cluster 지원   │ 클라이언트 샤딩            │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 스레드 모델      │ 싱글 스레드          │ 멀티 스레드                │
│                  │ (6.0+ I/O 멀티스레드)│                            │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ Pub/Sub          │ 지원                 │ 미지원                     │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 사용 사례        │ 캐시 + 세션 + 큐 등 │ 순수 캐시만                │
│                  │ 다목적              │                            │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 현재 추세        │ 압도적 주류          │ 사용 감소                  │
└──────────────────┴──────────────────────┴────────────────────────────┘

5.4 Spring Boot에서 H2 인메모리 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# application-test.yml (테스트 환경)
spring:
  datasource:
    url: jdbc:h2:mem:testdb        # 인메모리 모드
    driver-class-name: org.h2.Driver
    username: sa
    password:
  jpa:
    database-platform: org.hibernate.dialect.H2Dialect
    hibernate:
      ddl-auto: create-drop        # 테스트 시작 시 생성, 종료 시 삭제
  h2:
    console:
      enabled: true                 # H2 콘솔 활성화 (/h2-console)

H2는 MySQL 호환 모드도 지원한다: jdbc:h2:mem:testdb;MODE=MySQL


면접에서 자주 묻는 질문

Q1. DELETE, TRUNCATE, DROP의 차이는?

DELETE는 DML로 행 단위 삭제가 가능하고 롤백할 수 있으며, 각 행 삭제를 로그에 기록합니다. TRUNCATE는 DDL로 전체 데이터를 빠르게 삭제하지만 롤백이 불가능하고 AUTO_INCREMENT가 초기화됩니다. DROP은 DDL로 테이블 자체를 제거합니다. DELETE는 조건부 삭제 시, TRUNCATE는 테이블 초기화 시, DROP은 테이블이 불필요할 때 사용합니다.

Q2. 클러스터링과 샤딩의 차이는?

클러스터링은 같은 데이터를 여러 서버에 복제하여 고가용성과 읽기 부하 분산을 달성합니다. 샤딩은 데이터를 나누어 여러 서버에 분산 저장하여 수평 확장을 달성합니다. 클러스터링은 모든 서버가 전체 데이터를 갖지만, 샤딩은 각 서버가 데이터의 일부만 담당합니다. 보통 클러스터링과 샤딩을 함께 사용합니다.

Q3. 파티셔닝은 왜 하나요?

대용량 테이블에서 쿼리 성능을 향상시키기 위해서입니다. 수억 건의 주문 테이블을 연도별로 Range 파티셔닝하면, 특정 연도 조회 시 해당 파티션만 스캔합니다(Partition Pruning). 또한 오래된 데이터를 파티션 단위로 빠르게 삭제(DROP PARTITION)할 수 있어 데이터 관리도 효율적입니다.

Q4. 동적 쿼리와 정적 쿼리의 차이는?

정적 쿼리는 SQL 구조가 고정되고 파라미터만 변하는 쿼리입니다. Prepared Statement로 실행되어 실행 계획 재사용과 SQL Injection 방지가 가능합니다. 동적 쿼리는 검색 조건에 따라 WHERE, JOIN 등 SQL 구조 자체가 변하는 쿼리입니다. MyBatis의 XML 태그나 QueryDSL로 안전하게 구현해야 하며, 문자열 연결 방식은 SQL Injection 위험이 있어 사용하면 안 됩니다.

Q5. DB 마이그레이션 시 가장 중요한 고려사항은?

하위 호환성무중단 운영입니다. 컬럼 추가/삭제 시 이전 버전 애플리케이션과의 호환성을 보장해야 하고, 대용량 테이블의 ALTER TABLE은 락이 발생할 수 있으므로 온라인 DDL 도구를 사용합니다. 확장-축소 전략(컬럼 추가 → 코드 배포 → 기존 컬럼 삭제)으로 3단계로 진행하고, 반드시 롤백 계획과 데이터 백업을 준비합니다.

Q6. In-Memory DB는 언제 사용하나요?

빠른 읽기/쓰기가 필요한 보조 저장소로 사용합니다. Redis를 캐시, 세션, 분산 락, Rate Limiting 등에 활용하고, H2를 테스트 환경 DB로 사용합니다. 메인 저장소 대신이 아니라, 디스크 DB와 함께 사용하여 자주 접근하는 데이터의 응답 속도를 높이는 것이 일반적입니다. 전원 장애 시 데이터 유실 가능성이 있으므로 영속화 설정에 주의합니다.

Q7. Flyway 같은 마이그레이션 도구를 왜 쓰나요?

DB 스키마 변경을 버전으로 관리하여, 어떤 변경이 언제 적용되었는지 추적할 수 있습니다. 개발-스테이징-운영 환경에서 동일한 스키마를 보장하고, 새 서버 구축 시 처음부터 순서대로 마이그레이션을 자동 실행합니다. 수동 SQL 실행의 실수를 방지하고, Git과 함께 스키마 변경 이력을 코드 리뷰할 수 있다는 장점이 있습니다.


핵심 정리: DELETE/TRUNCATE/DROP은 삭제 범위와 롤백 가능 여부가 핵심 차이이고, 클러스터링(고가용성)·파티셔닝(쿼리 성능)·샤딩(수평 확장)은 목적이 다르다. 동적 쿼리는 반드시 안전한 방식(QueryDSL, MyBatis 태그)으로 구현하고, DB 마이그레이션은 Flyway로 버전 관리하며, In-Memory DB는 메인 DB의 보조 저장소로 활용한다.