1일 1CS(Computer Science)

데이터베이스 정규화에 대해서 설명해주세요.

표자 2025. 7. 10. 10:07

정규화가 뭔가요? 🤔

정규화는 마치 옷장 정리와 같습니다! 🧥👔👗

지금 여러분의 옷장을 상상해보세요. 같은 옷이 여러 곳에 걸려있고,

양말 한 짝은 침실에, 다른 한 짝은 세탁실에 있다면... 정말 복잡하죠?

데이터베이스도 마찬가지입니다. 같은 정보가 여러 곳에 중복되어 저장되면

  • 저장 공간 낭비 💸
  • 데이터 수정 시 실수 발생 🚫
  • 데이터 불일치 문제 😵

정규화는 이런 문제들을 해결하기 위해 테이블을 깔끔하게 정리하는 과정입니다!

1정규화(1NF) - 하나의 칸에는 하나의 값만! 📦

잘못된 예시 ❌

| 학생명 | 수강과목 |
|--------|----------|
| 김철수 | 수학, 영어, 과학 |
| 이영희 | 국어, 역사 |

올바른 예시 ✅

| 학생명 | 수강과목 |
|--------|----------|
| 김철수 | 수학 |
| 김철수 | 영어 |
| 김철수 | 과학 |
| 이영희 | 국어 |
| 이영희 | 역사 |

마치 서랍 정리와 같습니다! 양말 서랍에는 양말만, 속옷 서랍에는 속옷만 넣는 것처럼 📦

2정규화(2NF) - 기본키 전체에 의존하게 만들기! 🔑

문제 상황

카페 주문 테이블을 생각해보세요 ☕

| 주문번호 | 메뉴명 | 가격 | 직원명 |
|----------|---------|------|--------|
| 001 | 아메리카노 | 4000 | 김바리스타 |
| 002 | 라떼 | 4500 | 김바리스타 |
| 003 | 아메리카노 | 4000 | 이바리스타 |

여기서 메뉴 가격은 주문번호와 상관없이 메뉴명에만 의존하죠? 이게 문제입니다! 🚨

해결책

테이블을 분리합니다:

주문 테이블

| 주문번호 | 메뉴명 | 직원명 |
|----------|---------|--------|
| 001 | 아메리카노 | 김바리스타 |
| 002 | 라떼 | 김바리스타 |

메뉴 테이블

| 메뉴명 | 가격 |
|---------|------|
| 아메리카노 | 4000 |
| 라떼 | 4500 |

3정규화(3NF) - 이행적 종속 제거하기! 🔄

문제 상황

학생 정보 테이블을 봅시다 🎓

| 학번 | 학생명 | 학과코드 | 학과명 |
|------|---------|----------|--------|
| 2021001 | 김철수 | CS | 컴퓨터공학과 |
| 2021002 | 이영희 | EE | 전자공학과 |

여기서 학과명은 학번 → 학과코드 → 학과명 순으로 결정됩니다. 이게 이행적 종속! 🔄

해결책

학생 테이블

| 학번 | 학생명 | 학과코드 |
|------|---------|----------|
| 2021001 | 김철수 | CS |
| 2021002 | 이영희 | EE |

학과 테이블

| 학과코드 | 학과명 |
|----------|--------|
| CS | 컴퓨터공학과 |
| EE | 전자공학과 |

BCNF - 모든 결정자는 후보키여야 해! 👑

가장 엄격한 정규화 단계입니다. 모든 결정자가 반드시 후보키가 되어야 합니다.

예시 상황

수강신청 테이블에서 한 과목을 여러 교수가 가르치는 경우:

| 학번 | 과목 | 교수 | 강의실 |
|------|------|------|--------|
| 2021001 | 데이터베이스 | 김교수 | 101호 |
| 2021001 | 데이터베이스 | 이교수 | 102호 |

여기서 교수강의실을 결정하지만, 교수는 후보키가 아닙니다! 🚨

역정규화(Denormalization) - 때로는 중복이 필요해! 🔄

언제 사용하나요?

  • 조회 성능이 매우 중요할 때 🚀
  • 복잡한 JOIN이 자주 발생할 때 🔗
  • 실시간 통계가 필요할 때 📊

실제 예시

인스타그램 같은 SNS에서 게시글의 좋아요 수를 매번 계산하면 너무 느려요! 😵

그래서 posts 테이블에 likes_count 컬럼을 추가하고, 좋아요가 생길 때마다 이 값을 업데이트합니다.

// 좋아요 추가 시
await db.transaction(async (trx) => {
  await trx('likes').insert({ post_id, user_id });
  await trx('posts').where('id', post_id).increment('likes_count', 1);
});

역정규화의 단점 ⚠️

  • 데이터 중복으로 인한 저장 공간 증가 💾
  • 데이터 일관성 유지의 어려움 🔧
  • 업데이트 시 여러 테이블 수정 필요 📝

정규화 vs 역정규화 선택 기준 🤷‍♂️

정규화를 선택할 때 ✅

  • 데이터 일관성이 최우선
  • 쓰기 작업이 많은 시스템
  • 저장 공간 효율성이 중요
  • 데이터 무결성이 중요한 금융 시스템

역정규화를 선택할 때 ✅

  • 조회 성능이 최우선
  • 읽기 작업이 압도적으로 많음
  • 실시간 대시보드나 분석 시스템
  • 복잡한 JOIN 쿼리가 성능 병목

실무에서의 팁 💡

1. 단계별 접근 🎯

모든 테이블을 3NF까지 정규화한 후, 성능 이슈가 있는 부분만 선택적으로 역정규화하세요!

2. 캐싱 활용 🚀

Redis나 Memcached를 사용해서 자주 조회되는 데이터를 캐싱하면 역정규화 없이도 성능 향상 가능!

3. 읽기 전용 복제본 📚

마스터 DB는 정규화하고, 슬레이브 DB는 역정규화해서 조회 전용으로 사용하는 방법도 있어요!

마무리 🎯

정규화는 데이터 정리의 기본입니다! 하지만 무조건 높은 정규화가 좋은 것은 아니에요.

상황에 따라 적절한 수준의 정규화를 선택하고, 필요하면 역정규화도 고려해야 합니다.

마치 옷장 정리처럼 너무 세세하게 나누면 찾기 어려워지고, 너무 대충 정리하면 관리가 힘들어지죠! 🧥👔


면접 답변 💼

Q: 데이터베이스 정규화에 대해 설명해주세요.

A: 정규화는 데이터 중복을 최소화하고 데이터 무결성을 보장하기 위해 테이블을 체계적으로 분해하는 과정입니다. 1NF는 원자값 보장, 2NF는 부분 함수 종속 제거, 3NF는 이행적 종속 제거, BCNF는 모든 결정자가 후보키가 되도록 합니다. 하지만 조회 성능이 중요한 경우 역정규화를 통해 적절한 중복을 허용하기도 합니다.

 

Q: 언제 역정규화를 사용하나요?

A: 읽기 성능이 쓰기 성능보다 중요하고, 복잡한 JOIN으로 인한 성능 저하가 심할 때 사용합니다. 예를 들어 SNS의 좋아요 수나 게시글 수 같은 집계 데이터를 별도 컬럼으로 저장하여 실시간 조회 성능을 높이는 경우가 있습니다.


 

데이터베이스 정규화에 대해서 설명해주세요.

백엔드와 관련된 질문이에요.

데이터베이스에서 정규화(Normalization) 는 테이블을 정리하여 중복 데이터를 최소화하고, 데이터 무결성을 보장하는 과정을 의미합니다. 이를 통해 데이터 저장 용량을 줄이고, 삽입·갱신·삭제 이상(Anomaly) 현상을 해결할 수 있습니다. 정규화는 여러 단계가 존재하며, 대표적으로 1정규화(1NF), 2정규화(2NF), 3정규화(3NF), BCNF가 있습니다.

각 정규화 단계를 설명해주세요. 🤔

  • 1 정규화(1NF) 는 테이블 컬럼의 값이 원자값(Atomic Value)을 가지도록 정리하는 것을 의미합니다.
  • 2 정규화(2NF) 는 1 정규화를 진행한 테이블에서 완전 함수 종속을 만족할 수 있도록 테이블을 분해하는 것인데요. 쉽게 표현하자면, 기본 키의 일부에만 종속된 속성이 없도록 분해하는 것을 의미합니다. A 속성을 통해서 B 속성의 값이 유일하게 정해지는 관계에서 A를 결정자라고 합니다. 가령 사용자 ID가 기본 키이며 값이 1입니다. 그리고, 사용자 ID 1번에 대응되는 유일한 이름 속성 값이 "B" 이라고 했을 때, 이름 속성의 결정자는 사용자 ID입니다. 2NF를 만족하기 위해서는 기본키의 부분 집합이 결정자가 될 수 없습니다.
  • 3 정규화(3NF) 는 2 정규화를 진행한 테이블에서 이행적 종속을 제거하기 위해 테이블을 분해하는 것을 의미합니다. A가 B를 결정하고, B가 C를 결정하는 경우에는 A가 C의 결정자가 되는데요. 이를 이행적 종속이라고 합니다. 3NF을 만족하기 위해서는 이행적 종속이 제거되도록 테이블을 분리해야 합니다.
  • BCNF 정규화 는 3 정규화를 진행한 테이블의 모든 결정자가 반드시 후보키가 될 수 있도록 테이블을 분해하는 것을 의미합니다. BCNF를 만족하기 위해서는 후보키가 아닌 결정자가 존재하지 않도록 테이블을 분리해야 합니다.

역정규화에 대해서 알고 계신가요? 🤓

역정규화(Denormalization) 는 정규화된 데이터베이스에서 쓰기 성능을 희생하고 읽기 성능을 향상하기 위해 사용되는 전략입니다. 예를 들어, 전체 게시글의 수나 좋아요의 수를 계산해 특정 컬럼에 저장해서 읽기 성능을 항상 시킬 수 있습니다. 역정규화된 데이터베이스에서는 데이터의 중복을 허용하기 때문에 데이터의 일관성을 맞추기 위한 추가적인 작업이 필요합니다.

728x90