포스트

정규화

정규화

뮨재 사항 제시: 하나의 거대한 테이블

order_idordered_atmember_idmember_namemember_addressproduct_info
10012025-08-201서울시 송파구10:노트북:2:1500000
15:키보드:1:50000
10022025-08-212네이트경기도 성남시10:노트북:1:1500000
10032025-08-211서울시 송파구20:머우스:1:30000
  • 갱신 이상: 만약 션 회원의 주소가 다른 주소로 변경 된다면, 션이 주문한 모든 데이터의 주소를 변경해야함
  • 삽입 이상: 아직 한 번도 주문하지 않은 새로운 회원을 시스템에 등록할수 없음
  • 삭제 이상: 1002번 주문 삭제 시, 네이트 고객의 유일한 주문이였다면 네이트라는 고객 자체가 사라짐

함수 종속성(Functional Dependency)

테이블에서 컬럼의 값들이 다른 컬럼의 값을 유일하게 결정하는 관계를 의미합니다.

X -> Y와 같이 표기하며 X가 Y를 함수적으로 결정한다 라고 읽습니다.

예시

  • member_id -> member_name: member_id가 1이면 member_name은 항상 션이다.

제1 정규화

🌟 제1 정규화

테이블의 모든 컬럼이 원자적(Atomic)인 값만을 가져야 한다.

order_idmember_idmember_nameproduct_idproduct_nameproduct_priceorder_quantityordered_at
1001110노트북150000022025-08-20 10:00:00
1001115키보드5000012025-08-20 10:00:00
10022네이트10노트북150000012025-08-21 11:00:00
1003120마우스3000012025-08-21 12:00:00

이제 모든 컬럼이 원자적 값을 갖게 되었습니다. 하지만 여전히 데이터 중복 문제가 남아있습니다.

1001번 주문의 션 회원 이름과 주문 날짜가 두 번이나 반복해서 저장됩니다. 이를 해결하기 위해 제2 정규형이 필요합니다.

제2 정규형

🌟 제2 정규형

  • 제1 정규형을 만족해야 한다.
  • 테이블의 모든 컬럼이 기본 키에 대해 완전 함수 종속 이어야 한다.
  • 즉, 부분 함수 종속이 없어야 한다.

(order_id, product_id)는 복합키 입니다. 즉, 주문 ID와 상품 ID를 합쳐야 하나의 행을 고유하게 식별할 수 있습니다.

기본 키 모두에 종속되는 컬럼들

  • (order_id, product_id) -> order_price
  • (order_id, product_id) -> order_quantity

기본 키의 일부에만 종속되는 컬럼들

  • order_id -> member_id
  • order_id -> member_name
  • order_id -> ordered_at
  • product_id -> product_name
  • product_id -> product_price

부분 함수 종속 컬럼 테이블 분리

  • orders
order_idmember_idmember_nameordered_at
100112025-08-20 10:00:00
10022네이트2025-08-21 11:00:00
100312025-08-21 12:00:00
  • product
product_idproduct_nameprice
10노트북1500000
15키보드50000
20마우스30000
  • order_item
order_idproduct_idorder_priceorder_quantity
10011015000002
100115500001
10021015000001
100320300001

제3 정규형

🌟 제3 정규형

  • 제2 정규형을 만족해야 한다.
  • 이행적 함수 종속이 존재하지 않아야 한다.

기본 키가 아닌 컬럼이 다른 컬럼을 결정하는 관계를 이행적 함수 종속이라고 합니다.

  • orders
order_idmember_idmember_nameordered_at
100112025-08-20 10:00:00
10022네이트2025-08-21 11:00:00
100312025-08-21 12:00:00

위 테이블에서 member_nameorder_id가 아닌 member_id에 종속 됩니다.

즉, order_id -> member_id -> member_name과 같은 이행적 함수 종속 관계가 나타납니다.

이행적 함수 종속 관계 테이블 분리

  • member
member_idmember_name
1
2네이트
  • orders
order_idmember_idordered_at
100112025-08-20 10:00:00
100222025-08-21 11:00:00
100312025-08-21 12:00:00

BCNF 정규형

🌟 BNCF(Boyce-codd Normal Form)

테이블의 모든 결정자가 후보키 여야 한다.

  • 결정자: 함수 종속 관계(X -> Y)에서 X에 해당하는, 즉 다른 컬럼의 값을 결정하는 컬럼을 의미
  • 후보 키: 테이블의 행을 유일하게 식별 할 수 있는 컬럼의 최소 집합
  • 기본키는 여러 후보 키 중 하나를 선택한 것

수강신청 시스템 설계

  • 한 학생은 여러 개의 특강을 신청할 수 있다.
  • 하나의 특강은 여러 명의 교수가 가르칠 수 있다.
  • 한 교수는 오직 하나의 특강만 담당한다.(이 규칙이 BCNF 위반을 만드는 핵심)
student_idlecture_nameprofessor_name
101데이터베이스김교수
101자바서교수
102데이터베이스박교수
103자바서교수

함수 종속성 분석

  • (student_id, lecture_name) -> professor_name 학생 ID와 특강 이름을 알면 담당 교수를 알 수 있다.
  • professor_name -> lecture_name: 교수의 이름을 알면 그가 담당하는 특강 이름을 알 수 있다(규칙 3번)

후보 키 분석

  • (student_id, lecture_name): 모든 컬럼을 결정함므로 후보 키가 될 수 있다.
  • (student_id, professor_name): 학생 ID와 교수 이름을 알면 lecture_name도 알 수 있으므로 이 조합 역시 후보키가 될 수 있다.

여기서는 (student_id, lecture_name)을 기본 키로 선택했다고 가정합니다.

정규형 만족 여부 확인

  • 제1 정규형: 모든 컬럼은 원자적 값을 가지므로 만족
  • 제2 정규형
    • 기본 키가 아닌 컬럼은 professor_name 하나뿐
    • 이 컬럼은 기본 키 전체에 종속되므로 부분 함수 종속이 없음
    • 만족
  • 제3 정규형
    • 기본 키가 아닌 컬럼이 다른 기본 키가 아닌 컬럼을 결정해야 함
    • 하지만 이 테이블에는 기본 키가 아닌 컬럼이 professor_name 하나뿐이므로, 이행적 종속이 발생할 수 없음
    • 만족
  • BCNF
    • 모든 결정자가 후보 키인가?
    • (student_id, lecture_name)professor_name을 결정
      • 이 결정자는 기본 키 이므로 후보 키다.
    • professor_namelecture_name을 결정
      • professor_name만으로는 행을 유일하게 식별할 수 없기 때문에 후보 키가 아니다.
      • BCNF 위반

BCNF 적용하여 테이블 분리

  • professor
professor_namelecture_name
김교수데이터베이스
박교수데이터베이스
서교수자바
  • enrollment
student_idprofessor_name
101김교수
101서교수
102박교수
103서교수

실무와 정규화

  • 정규화는 데이터 중복 최소화, 데이터 일관성 확보, 이상 현상 해결, 유연한 구조 확보를 위해 필요
  • 실무에서는 보통 제3 정규형이나 BCNF를 목표로 하지만, 조회 성능이 매우 중요한 경우 JOIN을 줄이기 위해 의도적으로 정규화를 위반하는 역정규화를 수행하기도 함
  • 뛰어난 설계는 시스템의 특성에 ㅁ자게 정규화와 역정규화 사이의 최적의 균형점을 찾는 것

참고

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.