데이터베이스 Day2 - 정규화

별이·2025년 4월 3일
post-thumbnail

데이터베이스 과정에서 배운 정규화에 대해 정리해 보려 한다. 처음 들었을 때 이해가 안 되는 부분들이 많아 정리하면서 개념을 잡아보려 한다. 👩🏻‍💻💭

🔎 정규화란?

데이터베이스 설계 시 데이터의 중복을 최소화하고, 데이터 일관성과 무결성을 유지하기 위한 테이블 구조화 과정으로, 데이터의 결함을 제거하여 표준화된 형태로 만드는 것이다.
즉, '테이블을 잘 쪼개서 데이터 중복을 없애자!' 라고 생각하면 될 것 같다.

정규화의 목적

  • 데이터 중복 최소화: 동일한 데이터가 여러 곳에 저장되지 않도록 한다.
  • 데이터 일관성 유지: 한 데이터만 수정해도 모든 관련 데이터가 자동으로 갱신된다.
  • 데이터 무결성 보장: 데이터의 정확성과 신뢰성을 높인다.
  • 효율적 데이터 구조화: 쿼리 성능 향상 및 데이터베이스 용량 최적화

📝 정규화 단계별 정리

✨ 1정규화 (1NF)

  • 모든 속성(컬럼)이 원자값(Atomic Value)을 가져야 한다.
  • 테이블의 각 셀은 하나의 값만 가져야 한다.

💡 한 셀에 여러 전화번호를 저장하지 않고, 각각 별도의 행으로 분리

❌ Before 1NF
회원ID(1), 이름(민지), 연락처(010-0000-0000, 02-000-0000)

✅ After 1NF
회원ID(1), 이름(민지), 연락처(010-0000-0000)
회원ID(1), 이름(민지), 연락처(02-0000-0000)

✨ 2정규화 (2NF)

  • 부분적 함수 종속을 제거하는 것
  • 1정규화를 만족하며, 모든 비주요 속성이 주요 키에 완전 함수적으로 중속 되어야 한다.

주요 용어

  • 함수: 키 (값을 결정짓는 요소)
  • 함수 종속: 키로 식별되는 속성들 (A->B: A가 B를 결정한다)
  • 부분적 함수 종속: 식별 관계를 가지는 테이블에서 복합키의 일부분으로만 식별되는 속성들

예시

[주문] 테이블
(회원ID, 상품ID) -> (주문일자, 수량, 회원연락처, 상품명)

여기서 문제는 회원연락처는 회원ID만으로 결정되고, 상품명은 상품ID만으로 결정된다. 즉, 복합키(회원ID, 상품ID) 전체가 아닌 일부만으로 결정되는 부분적 함수 종속이 발생한다.

☑️ Before 2NF

회원ID상품ID주문일자수량회원연락처상품명
1A2025.01.012010-0000-0000아메키라노
2A2025.01.021010-1234-5678아메키라노

✅ After 2NF
[회원] 테이블

회원ID회원연락처
1010-0000-0000
2010-1234-5678

[상품] 테이블

상품ID상품명
A아메리카노

[주문] 테이블

회원ID상품ID주문일자수량
1A2025.01.012
2A2025.01.021

키의 종류

  • 주키(Primary Key): 테이블의 모든 행을 고유하게 식별하는 키
  • 후보키(Candidate Key): 주키가 될 수 있는 후보들
  • 대체키(Alternate Key): 주키로 선택되지 않은 후보키
  • 대리키(Surrogate Key): 인위적으로 만들어진 키(예: 일련번호)
  • 수퍼키(Super Key): 유일성은 만족하지만 최소성은 만족하지 않는 키
  • 외래키(Foreign Key): 다른 테이블의 주키를 참조하는 키

✨ 3정규화 (3NF)

  • 이행적 함수 종속을 제거하는 것
  • 2정규화를 만족하며, 비주요 속성끼리의 종속관계가 없어야 한다.
  • 이행적 함수 종속: 두 번 이상의 참조를 통해 식별되는 속성들 제거

전이적 관계 (Transitive Relation)

x > y 이고, y > z이면 x > z 이다.

예시

[주문] 테이블
주문ID -> 회원ID -> 회원연락처
주문ID -> 메뉴ID -> 메뉴명

이런 관계에서는 주문ID로 회원ID를 찾고, 회원ID로 회원연락처를 찾는 구조인데 이런 간적접인 참조 관계를 제거해야 한다.

☑️ Before 3NF

주문ID회원ID회원연락처메뉴ID메뉴명
1A010-0000-0000M1아메키라노

✅ After 3NF
[회원] 테이블

회원ID회원연락처
1010-0000-0000

[메뉴] 테이블

메뉴ID메뉴명
M1아메리카노

[주문] 테이블

주문ID회원ID메뉴ID
1AM1

✨ BCNF (Boyce-Codd 정규형)

  • 모든 결정자(Determinant)가 후보키(Candidate Key)여야 한다.
  • 3정규화를 만족하면서 추가적인 제약조건이 붙는다.
  • 결정자: 어떤 값을 기준으로 다른 값을 유일하게 정할 수 있는 속성(또는 속성 조합)

💡 3NF와 BCNF 차이 예시

상황: 학교에서 일정표를 만든다.

일정표(학생이름, 수업이름, 선생님, 교실번호)
  • 민지, 수학, 김선생님, 101호
  • 민지, 영어, 박선생님, 102호
  • 리나, 수학, 김선생님, 101호

규칙

  • 한 학생은 여러 수업을 들을 수 있다.
  • 한 수업은 항상 같은 선생님이 가르친다. (수학은 항상 김선생님)
  • 선생님들은 항상 같은 교실에서만 가르친다. (김선생님은 항상 101호)

📍 3NF
"선생님이 어떤 수업을 가르치는지는 기록해도 괜찮아!"
위의 일정표는 3NF이다. 약간의 반복이 있지만 괜찮다.
📍 BCNF
"아니야, 선생님이 어떤 수업을 가르치는지, 어떤 교실에서 가르치는지는 따로 기록하자!"

수업-선생님표: (수업이름, 선생님)
-수학, 김선생님
-영어, 박선생님

선생님-교실표: (선생님, 교실번호)
-김선생님, 101호
-박선생님, 102호

학생-수업표: (학생이름, 수업이름)
-민지, 수학
-민지, 영어
-리나, 수학

3NF: "일정표 하나로 관리해도 괜찮아!"(약간 중복되더라도)
BCNF: "정보는 딱 한 번만 쓰자. 필요할 때 여러 표를 보면 돼!"

=> 3NF는 약간의 중복을 허용하고, BCNF는 중복을 완전히 없애고 싶어 한다.

✨ 4정규화 (4NF)

  • 다치 종속(Multi-Valued Dependency)을 제거
  • 한 속성이 복수의 값을 가질 때, 다른 속성과 '곱' 형태로 튜플이 증식하는 현상 제거

예시

학생들이 여러 과목을 수강하는 경우의 문제

☑️ Before 4NF

이름과목
민지Javascript
리나Javascript
수지Javascript
민지Reactjs
리나Reactjs
수지Reactjs
민지Nextjs
리나Nextjs
수지Nextjs

이 구조는 학생 3명과 과목 3개의 모든 조합(9개)을 저장한다. 이는 다치 중속 문제이다.

✅ After 4NF
[학생] 테이블

학생ID이름
1민지
2리나
3수지

[과목] 테이블

과목ID과목명
1Javascript
2Reactjs
3Nextjs

[수강] 테이블

학생ID과목ID
11
12
13
21
22
......

🔄 draw.io로 그려본 ERD 다이어그램

배운 내용을 바탕으로 팀원들과 함께 ERD 다이어그램을 그려보았다. 각 정규화 단계별로 어떻게 테이블이 변화하는지 시가적으로 확인할 수 있어서 이해하는 데 도움이 되었다.


👩🏻‍💻💭

정규화 개념이 너무 추상적이고 어렵게 느껴졌는데, 예시와 다이어그램을 통해 차근차근 공부하니 점차 이해가 되어갔던 것 같다. 특히 3NF랑 BCNF를 차이점을 구분하는 게 어려웠는데 팀원들과 이야기 나눠가며 하다 보니 어느 정도 명확해진 것 같다. 앞으로 하게 될 프로젝트에서 데이터베이스를 설계해야 해서 그 과정에 참여를 하게 된다면 이러한 정규화 원칙을 적용하여 더 효율적이고 일관성 있는 시스템을 구축해 보고 싶다.

profile
💭

0개의 댓글