데이터베이스 면접 질문 완벽 정리: 인덱스, 트랜잭션, 정규화
·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 Read | Non-Repeatable Read | Phantom 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, PostgreSQL | MongoDB, Redis, Cassandra |
면접 빈출 질문 요약#
- 인덱스란? 검색 속도를 높이기 위한 B-Tree 기반 자료구조, 쓰기 성능과 트레이드오프
- ACID란? 원자성, 일관성, 격리성, 지속성 — 트랜잭션의 4가지 특성
- 정규화란? 데이터 중복을 줄이고 무결성을 높이는 테이블 설계 과정
- N+1 문제란? ORM에서 연관 데이터를 각각 조회해 N번의 추가 쿼리가 발생하는 문제
- SQL과 NoSQL 차이? 스키마 유무, 확장 방식, ACID 지원 여부
관련 포스트
면접 준비#CS#자료구조#면접#알고리즘
자료구조 면접 질문 완벽 정리: 스택, 큐, 트리, 해시
스택, 큐, 연결 리스트, 트리, 힙, 해시테이블까지 개발자 면접에 나오는 핵심 자료구조를 코드와 함께 정리했습니다.
·9분 읽기
면접 준비#알고리즘#CS#코딩테스트#면접
시간복잡도와 Big-O 표기법: 코딩테스트 필수 개념
코딩테스트와 면접에 반드시 필요한 시간복잡도와 Big-O 표기법을 실제 코드 예제와 함께 정리했습니다.
·7분 읽기
면접 준비#JavaScript#면접#CS
JavaScript 면접 질문 완벽 정리: 클로저, 호이스팅, 이벤트 루프
클로저, 호이스팅, this 바인딩, 이벤트 루프 등 프론트엔드 면접의 단골 JavaScript 질문들을 코드와 함께 정리했습니다.
·9분 읽기