1. 인덱스 (Index)
인덱스란?
데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조. 책의 목차처럼 특정 컬럼의 값과 해당 레코드의 물리적 위치를 매핑하여 빠른 검색을 가능하게 함.
인덱스를 사용하는 이유
- 검색 성능 향상: WHERE, JOIN, ORDER BY 절의 실행 속도 개선
- 정렬 비용 감소: 이미 정렬된 상태로 유지
- 전체 테이블 스캔 회피: 필요한 데이터만 빠르게 접근
인덱스의 장단점
장점:
- 검색 속도 대폭 향상 (O(log n))
- WHERE, ORDER BY, GROUP BY 절의 성능 개선
- MIN/MAX 값을 빠르게 조회
단점:
- 추가 저장 공간 필요 (테이블 크기의 약 10%)
- INSERT, UPDATE, DELETE 성능 저하 (인덱스도 함께 수정 필요)
- 잘못 설계된 인덱스는 오히려 성능 저하 유발
- 인덱스 유지보수 비용 발생
B-Tree 인덱스와 Hash 인덱스
구분B-Tree 인덱스Hash 인덱스
| 구조 | 균형 이진 트리 구조 | 해시 테이블 구조 |
| 검색 속도 | O(log n) | O(1) |
| 범위 검색 | 가능 (>, <, BETWEEN) | 불가능 (= 만 가능) |
| 정렬 | 자동 정렬 유지 | 정렬 불가 |
| 적합한 경우 | 범위 검색, 정렬이 필요한 경우 | 정확한 일치 검색만 필요한 경우 |
| 사용 | MySQL의 기본 인덱스 | Memory 엔진 등 특수한 경우 |
복합 인덱스 (Composite Index)
두 개 이상의 컬럼을 결합하여 만든 인덱스.
특징:
- 인덱스 컬럼 순서가 중요 (WHERE 절에서 앞쪽 컬럼부터 사용해야 효과적)
- 첫 번째 컬럼 기준으로 정렬 후, 두 번째 컬럼 정렬
- 예: INDEX(name, age) → WHERE name='김철수' ✅, WHERE age=30 ❌
사용 시점: 여러 컬럼을 함께 조회하는 쿼리가 빈번한 경우
2. 트랜잭션 (Transaction)
트랜잭션의 정의
데이터베이스의 상태를 변경하는 하나의 논리적 작업 단위. 여러 연산을 하나로 묶어 모두 성공하거나 모두 실패하도록 보장.
ACID 속성
A - Atomicity (원자성)
- 트랜잭션의 모든 연산이 완전히 수행되거나 전혀 수행되지 않아야 함
- All or Nothing 원칙
- 예: 계좌 이체 시 출금과 입금이 모두 성공하거나 모두 취소
C - Consistency (일관성)
- 트랜잭션 완료 후 DB는 일관된 상태를 유지해야 함
- 무결성 제약조건을 항상 만족
- 예: 잔액은 항상 0 이상이어야 함
I - Isolation (격리성)
- 동시에 실행되는 트랜잭션들이 서로 영향을 주지 않아야 함
- 트랜잭션 실행 중에는 다른 트랜잭션의 중간 결과를 볼 수 없음
D - Durability (지속성)
- 성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영됨
- 시스템 장애가 발생해도 커밋된 데이터는 보존
트랜잭션 격리 수준 (Isolation Level)
격리 수준Dirty ReadNon-Repeatable ReadPhantom Read설명
| READ UNCOMMITTED | O | O | O | 커밋되지 않은 데이터 읽기 가능 |
| READ COMMITTED | X | O | O | 커밋된 데이터만 읽기 가능 |
| REPEATABLE READ | X | X | O | 같은 데이터는 항상 동일하게 읽힘 |
| SERIALIZABLE | X | X | X | 완전한 격리, 성능 저하 |
용어 설명:
- Dirty Read: 커밋되지 않은 데이터를 읽는 현상
- Non-Repeatable Read: 같은 데이터를 다시 읽었을 때 값이 변경된 현상
- Phantom Read: 같은 조건으로 조회 시 없던 레코드가 나타나는 현상
커밋(Commit)과 롤백(Rollback)
커밋 (Commit):
- 트랜잭션의 모든 작업을 확정하여 DB에 영구 반영
- 커밋 후에는 되돌릴 수 없음
롤백 (Rollback):
- 트랜잭션의 모든 작업을 취소하고 이전 상태로 복구
- 오류 발생 시 자동 또는 수동으로 실행
데드락 (Deadlock)
정의: 두 개 이상의 트랜잭션이 서로가 점유한 리소스를 기다리며 무한 대기 상태에 빠지는 현상.
발생 예시:
- 트랜잭션 A: X 잠금 → Y 대기
- 트랜잭션 B: Y 잠금 → X 대기
- 서로 상대방이 점유한 자원을 기다림
해결 방법:
- 트랜잭션 순서 일관성 유지
- 트랜잭션 처리 시간 최소화
- 락 타임아웃 설정
- DBMS의 자동 데드락 감지 및 희생 트랜잭션 선택
3. JOIN
JOIN의 정의
두 개 이상의 테이블을 연결하여 데이터를 조회하는 연산. 관계형 데이터베이스에서 분산된 데이터를 결합하여 의미 있는 정보를 추출.
JOIN을 사용하는 이유
- 정규화된 테이블 결합: 중복을 제거한 여러 테이블의 데이터를 조합
- 데이터 통합 조회: 필요한 정보를 한 번에 조회
- 저장 공간 효율성: 중복 데이터 저장 없이 필요 시 결합
JOIN 종류와 특징
INNER JOIN
- 두 테이블에서 조건이 일치하는 행만 반환
- 교집합 개념
SELECT * FROM A INNER JOIN B ON A.id = B.id;
LEFT (OUTER) JOIN
- 왼쪽 테이블의 모든 행 반환, 오른쪽 테이블은 일치하는 행만 반환
- 일치하지 않으면 NULL 반환
SELECT * FROM A LEFT JOIN B ON A.id = B.id;
RIGHT (OUTER) JOIN
- 오른쪽 테이블의 모든 행 반환, 왼쪽 테이블은 일치하는 행만 반환
- LEFT JOIN의 반대
SELECT * FROM A RIGHT JOIN B ON A.id = B.id;
FULL (OUTER) JOIN
- 양쪽 테이블의 모든 행 반환
- 일치하지 않는 부분은 NULL 반환
- MySQL은 미지원 (UNION으로 구현)
CROSS JOIN
- 두 테이블의 모든 조합(카테시안 곱) 반환
- A 테이블 n개 행 × B 테이블 m개 행 = n×m개 결과
SELECT * FROM A CROSS JOIN B;
SELF JOIN
- 같은 테이블을 두 번 사용하여 JOIN
- 계층 구조 데이터 조회 시 유용
SELECT e.name, m.name AS manager
FROM Employee e JOIN Employee m ON e.manager_id = m.id;
4. 정규화 (Normalization)
정규화란?
데이터의 중복을 최소화하고 무결성을 유지하기 위해 테이블을 분해하는 과정.
목적:
- 데이터 중복 제거
- 이상 현상 방지 (삽입, 수정, 삭제 이상)
- 데이터 무결성 유지
- 저장 공간 효율화
정규화의 종류
제1정규형 (1NF)
- 모든 속성 값이 **원자값(Atomic Value)**을 가져야 함
- 반복 그룹 제거
- 예: 취미: 독서, 운동 ❌ → 별도 행으로 분리 ✅
제2정규형 (2NF)
- 1NF 만족 + 부분 함수 종속 제거
- 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속
- 복합키의 일부에만 종속되는 속성 분리
제3정규형 (3NF)
- 2NF 만족 + 이행 함수 종속 제거
- 기본키가 아닌 속성들 간의 종속 관계 제거
- 예: 학생ID → 학과 → 학과위치 (학과위치를 별도 테이블로 분리)
BCNF (Boyce-Codd Normal Form)
- 3NF 만족 + 모든 결정자가 후보키
- 3NF보다 엄격한 조건
제4정규형 (4NF)
- BCNF 만족 + 다치 종속 제거
제5정규형 (5NF)
- 4NF 만족 + 조인 종속성 제거
실무: 대부분 3NF까지 정규화
역정규화 (Denormalization)
언제 진행하나?
- 조회 성능이 중요한 경우: 여러 테이블 JOIN으로 성능 저하 발생
- 읽기 작업이 압도적으로 많은 경우: 쓰기보다 읽기가 훨씬 빈번
- 집계/통계 조회가 빈번한 경우: 미리 계산된 값 저장
- 실시간 응답이 중요한 경우: JOIN 비용 감소 필요
방법:
- 테이블 통합
- 중복 컬럼 추가
- 파생 컬럼 추가 (계산된 값 저장)
- 요약 테이블 생성
주의: 데이터 일관성 유지 부담 증가
5. SQL문
DDL (Data Definition Language) - 데이터 정의어
정의: 데이터베이스 구조를 정의하고 변경하는 명령어
예시:
- CREATE: 테이블, 인덱스, 뷰 생성
- ALTER: 테이블 구조 변경
- DROP: 테이블, 인덱스, 뷰 삭제
- TRUNCATE: 테이블 데이터 전체 삭제 (구조 유지)
DML (Data Manipulation Language) - 데이터 조작어
정의: 데이터를 조회, 삽입, 수정, 삭제하는 명령어
예시:
- SELECT: 데이터 조회
- INSERT: 데이터 삽입
- UPDATE: 데이터 수정
- DELETE: 데이터 삭제
DCL (Data Control Language) - 데이터 제어어
정의: 데이터 접근 권한을 제어하는 명령어
예시:
- GRANT: 권한 부여
- REVOKE: 권한 회수
기본 SQL문 작성 예시
-- INSERT: 데이터 삽입
INSERT INTO users (name, age, email)
VALUES ('김철수', 30, 'kim@example.com');
-- DELETE: 데이터 삭제
DELETE FROM users WHERE age < 20;
-- ALTER: 테이블 구조 변경
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- DROP: 테이블 삭제
DROP TABLE old_users;
-- SELECT 종합 쿼리
SELECT
u.name,
u.age,
COUNT(o.id) AS order_count,
SUM(o.amount) AS total_amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.age >= 20
GROUP BY u.id, u.name, u.age
HAVING COUNT(o.id) > 0
ORDER BY total_amount DESC;
절 실행 순서: FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
6. SQL 인젝션 (SQL Injection)
SQL 인젝션이란?
악의적인 사용자가 입력값을 조작하여 의도하지 않은 SQL 쿼리를 실행시키는 보안 취약점 공격 기법.
발생 상황
취약한 코드 예시:
String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
공격 시나리오:
- 입력값: username = "admin' --", password = "anything"
- 실행 쿼리: SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything'
- 결과: 비밀번호 확인 없이 admin 계정 로그인 성공
해결 방법
1. Prepared Statement (권장)
- 쿼리와 데이터를 분리하여 전송
- 자동으로 특수문자 이스케이프 처리
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM users WHERE username = ? AND password = ?"
);
pstmt.setString(1, username);
pstmt.setString(2, password);
2. ORM 사용
- JPA, Hibernate 등 ORM 프레임워크 사용
- 내부적으로 Prepared Statement 사용
3. 입력값 검증
- 화이트리스트 방식으로 허용된 문자만 입력 허용
- 특수문자, SQL 키워드 필터링
4. 저장 프로시저 사용
- 미리 컴파일된 쿼리 사용
5. 최소 권한 원칙
- DB 사용자에게 필요한 최소 권한만 부여
- DROP, ALTER 등 위험한 권한 제한
7. 쿼리 성능 최적화
최적화 작업 방법
1. 인덱스 최적화
- WHERE, JOIN, ORDER BY에 사용되는 컬럼에 인덱스 생성
- 복합 인덱스 순서 최적화
- 불필요한 인덱스 제거
2. 쿼리 재작성
- SELECT * 대신 필요한 컬럼만 조회
- 서브쿼리보다 JOIN 사용 (경우에 따라)
- UNION ALL 사용 (중복 제거 불필요 시)
- EXISTS 사용 (IN보다 효율적인 경우 많음)
3. 실행 계획 분석
- EXPLAIN 명령어로 쿼리 실행 계획 확인
- Full Table Scan 확인 및 개선
- 인덱스 사용 여부 확인
4. 정규화/역정규화
- 읽기 성능을 위한 역정규화 고려
- 계산된 값을 미리 저장
5. 페이징 처리
- LIMIT, OFFSET 사용으로 필요한 데이터만 조회
- 커서 기반 페이징 사용
6. 캐싱 활용
- Redis 등을 이용한 쿼리 결과 캐싱
- 자주 조회되는 데이터는 애플리케이션 레벨에서 캐싱
7. 파티셔닝
- 대용량 테이블을 논리적/물리적으로 분할
- 범위, 리스트, 해시 파티셔닝
8. 배치 처리
- 대량 INSERT/UPDATE는 배치로 처리
- 트랜잭션 크기 조절
9. 통계 정보 업데이트
- 옵티마이저가 올바른 실행 계획을 세우도록 통계 정보 최신화
10. N+1 문제 해결
- Fetch Join, Batch Size 설정 등
'개발공부 > 취업관련' 카테고리의 다른 글
| 신입 면접에서 자주 묻는 질문 정리 - 자바스크립트(JavaScript)편 (1) | 2025.10.04 |
|---|---|
| 신입 면접에서 자주 묻는 질문 정리 - 알고리즘(Algorithm) 편 (0) | 2025.10.04 |
| 신입 면접에서 자주 묻는 질문 정리 - 네트워크(Network)편 (1) | 2025.10.04 |
| 신입 면접에서 자주 묻는 질문 정리 - 스프링 부트(Spring Boot)편 (0) | 2025.10.04 |
| 신입 면접에서 자주 묻는 질문 정리 - 자바(JAVA)편 (0) | 2025.10.04 |