devlog.

데이터베이스 면접 질문 완벽 정리: 인덱스, 트랜잭션, 정규화

·10분 읽기

데이터베이스는 백엔드 개발자 면접에서 가장 깊게 파고드는 영역 중 하나입니다. 인덱스부터 트랜잭션, 정규화, 쿼리 최적화까지 면접관이 자주 묻는 질문들을 정리했습니다.

인덱스 (Index)#

인덱스란?#

테이블의 특정 컬럼에 대해 빠른 검색을 위한 자료구조입니다. 책의 목차와 같은 역할을 합니다.

-- 인덱스 없이 조회: Full Table Scan (O(N))
SELECT * FROM users WHERE email = 'hong@example.com';

-- 인덱스 생성
CREATE INDEX idx_users_email ON users(email);

-- 인덱스 사용 후 조회: B-Tree 검색 (O(log N))
SELECT * FROM users WHERE email = 'hong@example.com';

B-Tree 인덱스 구조#

          [50]
         /    \
      [25]    [75]
      /  \    /  \
   [10] [30] [60] [90]

루트에서 시작해 비교하며 내려가 O(log N)으로 검색합니다.

인덱스의 단점#

  • 저장 공간 추가 사용: 인덱스도 디스크를 차지
  • 쓰기 성능 저하: INSERT/UPDATE/DELETE 시 인덱스도 갱신
  • 인덱스가 항상 사용되지 않음: 옵티마이저가 Full Scan이 낫다고 판단하면 무시

복합 인덱스 (Composite Index)#

CREATE INDEX idx_name_age ON users(last_name, first_name, age);

-- ✅ 인덱스 사용: 앞 컬럼부터 순서대로 사용
WHERE last_name = '홍'
WHERE last_name = '홍' AND first_name = '길동'

-- ❌ 인덱스 미사용: 첫 번째 컬럼 없이는 사용 불가
WHERE first_name = '길동'
WHERE age = 30

트랜잭션과 ACID#

ACID란?#

속성영문설명
원자성Atomicity모두 성공하거나 모두 실패
일관성Consistency트랜잭션 전후 데이터 무결성 유지
격리성Isolation동시 실행 트랜잭션 간 독립성
지속성Durability커밋된 데이터는 영구 저장
BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 50000 WHERE id = 1; -- 출금
UPDATE accounts SET balance = balance + 50000 WHERE id = 2; -- 입금

-- 원자성: 둘 다 성공해야 커밋, 하나라도 실패하면 롤백
COMMIT;
-- 실패 시
ROLLBACK;

격리 수준 (Isolation Level)#

격리 수준Dirty ReadNon-Repeatable ReadPhantom Read
READ UNCOMMITTED발생발생발생
READ COMMITTED방지발생발생
REPEATABLE READ방지방지발생
SERIALIZABLE방지방지방지
  • Dirty Read: 커밋되지 않은 데이터를 읽음
  • Non-Repeatable Read: 같은 쿼리가 다른 결과 반환
  • Phantom Read: 없던 행이 나타나거나 있던 행이 사라짐

정규화 (Normalization)#

데이터 중복을 줄이고 무결성을 높이는 과정입니다.

1NF (1정규형)#

  • 각 컬럼은 하나의 값만 가져야 함 (원자값)
❌ 비정규형
| id | name | tags          |
|----|------|---------------|
| 1  | 홍길동 | Java, Python  |  ← 다중 값

✅ 1NF
| id | name | tag    |
|----|------|--------|
| 1  | 홍길동 | Java   |
| 1  | 홍길동 | Python |

2NF (2정규형)#

  • 1NF + 부분 함수 종속 제거 (복합 키의 일부에만 종속된 컬럼 분리)

3NF (3정규형)#

  • 2NF + 이행 함수 종속 제거 (A→B→C 관계에서 B 분리)

정규화 vs 반정규화#

구분정규화반정규화
목적중복 제거, 무결성조회 성능 향상
방법테이블 분리테이블 합치기, 중복 허용
장점저장 효율, 수정 용이조인 감소, 빠른 조회
단점조인 증가데이터 중복, 수정 비용

실무에서는 OLTP(거래)는 정규화, OLAP(분석)은 반정규화를 선택하는 경우가 많습니다.

N+1 문제#

ORM 사용 시 자주 발생하는 성능 문제입니다.

// ❌ N+1 문제 발생
const users = await User.findAll() // 쿼리 1번

for (const user of users) {
  const posts = await user.getPosts() // 유저마다 쿼리 N번
}
// 총 1 + N번의 쿼리

// ✅ Eager Loading으로 해결
const users = await User.findAll({
  include: [{ model: Post }] // JOIN으로 한 번에 조회
})
// 총 1번의 쿼리
-- 생성되는 쿼리 비교
-- N+1: SELECT * FROM posts WHERE user_id = 1;
--      SELECT * FROM posts WHERE user_id = 2; ...

-- Eager Loading:
SELECT users.*, posts.*
FROM users
LEFT JOIN posts ON posts.user_id = users.id;

SQL vs NoSQL#

구분SQL (관계형)NoSQL
스키마고정 (강제)유연 (동적)
확장수직 확장수평 확장
트랜잭션ACID 지원제한적 (BASE)
조인지원미지원 또는 제한적
사용 예금융, 쇼핑몰SNS, 로그, 캐시
대표 제품MySQL, PostgreSQLMongoDB, Redis, Cassandra

면접 빈출 질문 요약#

  • 인덱스란? 검색 속도를 높이기 위한 B-Tree 기반 자료구조, 쓰기 성능과 트레이드오프
  • ACID란? 원자성, 일관성, 격리성, 지속성 — 트랜잭션의 4가지 특성
  • 정규화란? 데이터 중복을 줄이고 무결성을 높이는 테이블 설계 과정
  • N+1 문제란? ORM에서 연관 데이터를 각각 조회해 N번의 추가 쿼리가 발생하는 문제
  • SQL과 NoSQL 차이? 스키마 유무, 확장 방식, ACID 지원 여부

관련 포스트