[DB] 정규화

2026. 5. 14. 12:00·CS/데이터베이스

정규화

데이터베이스 이상현상

데이터베이스를 다룰 때 데이터베이스를 그냥 값만 저장하는 용도로 사용하는 것보다는, 보다 더 효율적으로 데이터베이스를 설계해야한다. 비용도 비용이지만 다음과 같은 이상현상이 발생할 수도 있기 때문이다.

 

삽입이상

데이터를 저장할 때 불필요한 데이터를 추가해야하는 상황이다.

저번처럼 영화관 데이터베이스를 가져왔다. 상영관은 1개인 소규모 극장이기 때문에 상영할 영화의 정보만 데이터베이스에 저장하고, 모든 영화와 상영정보를 한 테이블에서 관리하고 있다.

 

만약 새 영화가 등록되었지만, 아직 상영시각이 정해지지 않았다면 시작시간을 NULL로 채워야할 것이다. 즉, 시작시간을 "정해지지 않음"이라는 시작시간을 불필요하게 추가해야한다.

 

갱신이상

영화의 인기가 너무 좋아서 만약 5번째 상영영화를 김씨표류기에서 타짜로 변경한다고하자. 그럼 영화ID만 바꾸는게 아니라 영화이름, 감독, 개봉일까지 연쇄적으로 정보를 수정해야 오류가 발생하지 않을 것이다.

 

이처럼 속성값 갱신 시 일부 속성만 갱신되어 모순이 발생하는 상황을 갱신이상이라고한다.

 

삭제이상

만약 라이선스 이슈로 인해 영화관에서 포화속으로를 상영할 수 없다고한다. 즉, 2026년 6월 1일 18시 상영영화가 없어지는 것. 그래서 테이블에서 값을 삭제시켰으나, 데이터베이스에서 포화속으로라는 영화의 정보도 사라지고 말았다. 즉, 하나의 데이터를 없애기 위해 다른 데이터까지 불필요하게 없어지는 것을 삭제이상이라고 칭한다.

 

 

데이터베이스에서 이상현상이 발생하면 메모리 낭비 뿐 아니라 데이터를 정확하게 저장하지 못한다. 따라서 이 이상현상들을 방지해야 효과적인 데이터베이스 관리가 가능한데, 이 때 쓰이는 것이 정규화.

정규화는 제1정규화부터 6개의 과정이 있으며, 정규화를 거칠수록 이상현상이 발생할 가능성이 줄어든다. 모든 정규화는 이전 단계이 정규화를 충족시키는 것을 기본으로한다.


제1정규화 (1NF)

도메인은 원자값으로만 구성되어야한다

 

원자값이란 업무 상으로 더 이상 쪼개지지 않는 단위를 뜻한다. 즉, 테이블에 저장되는 데이터들이 더 이상 다른 테이블들로 쪼개지지 않아야한다. 업무 상이 붙은 이유는 원자값으로 구성된 것 같아보이지 않아도 업무 상 굳이 나눠야할 필요가 없다면 제1정규화를 충족시키기 때문이다.

 

영화DB에 새 영화가 등록되었는데, 특이하게 감독이 두 명인 영화가 추가되었다.

이런 상황에서 영화 "인터스텔라"는 제1정규화를 지킨다고 할 수 없다. 왜냐하면 감독을 네일 감독과 쿠싱 감독으로 다시 나눌 수 있기 때문이다.

 

그래서 테이블을 분리해줬다. 영화 테이블은 영화이름과 감독컬럼을 복합키로하는 테이블로 만들었다. 따라서 영화와 감독, 영화감독정보 테이블 모두 저장하는 데이터를 더 이상 쪼갤 수 없는 형태로 저장하기 때문에 제1정규화를 충족시킨다고 볼 수 있다.

 

 

제1정규화로 삭제이상을 방지할 수 있다. 제1정규화가 잘 완료되면 테이블에는 더 이상 쪼갤 수 없는, 필수적인 컬럼들만 남기 때문에 다른 테이블 또는 컬럼에 영향을 주지 않고 안전하게 데이터를 삭제할 수 있다. 아까 삭제이상을 다룰 때처럼 인터스텔라의 포화속으로의 상영이 취소되더라도 상영테이블에서만 값을 지우고 영화테이블에는 안전하게 남겨둘 수 있기 때문이다.


제2정규화 (2NF)

완전 함수 종속을 만족하는 테이블을 설계하라

 

완전함수종속이란 복합키에서 등장하는 개념이다. 복합키를 사용하는 테이블에서, 복합키에 참여하지 않는 모든 데이터들이 복합키에 참여하는 데이터들을 모두 필요로 할 때를 완전함수종속이라고한다. 말이 좀 어려운데,

 

아까 제1정규화에서 이런 구조를 만들어냈는데, 영화 테이블에서 PK는 영화이름과 감독 컬럼을 복합키로 사용 중이다.

개봉일 컬럼은 반드시 영화이름과 감독을 확인해야하므로 복합키의 요소들을 전부 필요로하지만, 감독생일 컬럼의 경우에는 영화이름은 확인하지 않아도된다. 즉, 특정 컬럼이나 속성이 복합키에 참여 중인 모든 요소를 필요로하지 않는 상황 부분 함수 종속이라고한다. 위에서는 감독생일의 경우 복합키 중에 하나인 영화이름 속성을 필요로하지 않으므로 부분 함수 종속이라고 볼 수 있다.

 

따라서 부분 함수 종속의 경우에는 새로운 테이블로 분리해줄 수 있다. 이제 영화 테이블은 모든 데이터들이 모든 복합키에 참여 중인 데이터들을 필요로하므로 완전 함수 종속이다.

 

이처럼 복합키를 사용하는 테이블에서 모든 비주요속성(복합키에 참여 중이지 않은 속성)들이 복합키에 참여 중인 속성 전체에 의존하도록하는 (완전 함수 종속) 과정을 제2정규화라고 칭한다.

 

제2정규화로 갱신이상을 예방할 수 있다. 기존상황에서 영화의 감독이 바뀌면 감독이름과 감독생일을 모두 바꿔야하는 갱신이상의 상황이 생겼지만, 제2정규화를 통해 감독의 이름만 교체하면되므로 갱신이상을 방지했다.


제3정규화 (3NF)

이행 함수 종속을 제거하라

 

이행적 종속이란 테이블에서 A를 알고 있다면 B를 알 수 있고, B를 알고 있다면 C를 알 수 있어서 A를 안다면 바로 C를 알 수 있는 상황을 뜻한다. 때로는 PK가 아닌 컬럼에 의해 값이 결정되는 경우로도 본다.

 

생각해보니까 영화감독도 겹칠 수 있고, 영화이름도 겹칠 수 있기 때문에 ID값을 기반으로 컬럼을 수정했다. 추가적으로 영화와 감독이 N:M 관계이므로 중간에 테이블을 추가해 더 효과적으로 N:M 관계를 처리하게 설계했다. 이제 영화를 알 때 감독을 알고 싶다면 영화ID 값을 감독정보에게 전해주면 된다.

 

하지만 여기서 감독정보 테이블에 문제가 있는데, PK는 ID지만, 영화이름과 감독이름 속성은 각각 영화ID와 감독ID 속성에 의해 결정된다. 즉, PK가 아니라 다른 값에 종속 중인 상황이다. 이처럼 한 속성의 값이 PK가 아닌 속성에 의해 결정되는 상황을 이행적 종속(이행 함수 종속)이라하며 제3정규화는 이를 제거하는 것이다.

 

제3정규화에서는 C를 분리할 수 있다. 즉, PK가 아닌 속성에 의존적인 속성을 분리하는 것이다. 위의 예시에서는 감독ID와 감독이름, 영화ID와 영화이름 등을 새 테이블으로 분리하고, 기존 감독정보 컬럼에는 영화ID와 감독ID만을 남겨두면 제3정규화를 할 수 있다.

 

갱신이상(영화의 감독정보가 바뀌면 ID과 감독이름을 수정해야하는 등..)을 방지할 수 있다.


이처럼 정규화는 데이터를 안전하게 보관하고, 무결함, 이상현상 방지를 위해서 필요하다. 정규화를 통해서 데이터가 실수로 사라지거나, 중복되는 등의 여러 문제를 막을 수 있다.

 

정규화는 3NF 이외에도 보이스-코드 정규화(BCNF), 제4정규화(4NF), 제5정규화(5NF)가 존재하는데, 지나친 정규화는 데이터를 지나치게 쪼개 JOIN의 증가, 쿼리 복잡도 증가 등으로인해 오히려 성능저하를 초래할 수 있어 보통 3NF까지만 사용하고, 오히려 성능을 위해 반정규화도 실시한다고한다.

'CS > 데이터베이스' 카테고리의 다른 글

[DB] 기초데이터베이스 개념 간단정리  (0) 2026.05.13
[백엔드] JDBC에서 스프링 JPA까지, 그리고 영속성  (0) 2026.03.24
[DB] DB 설계 및 구축 독서 #1 - 데이터모델링과 데이터모델링 3요소, 엔티티, 속성, 관계  (0) 2026.01.14
'CS/데이터베이스' 카테고리의 다른 글
  • [DB] 기초데이터베이스 개념 간단정리
  • [백엔드] JDBC에서 스프링 JPA까지, 그리고 영속성
  • [DB] DB 설계 및 구축 독서 #1 - 데이터모델링과 데이터모델링 3요소, 엔티티, 속성, 관계
컬러잇
컬러잇
탄천러너지망생
  • 컬러잇
    Color it
    컬러잇
  • 전체
    오늘
    어제
    • 분류 전체보기 (235)
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (72)
        • JVM (12)
        • 인프라 (5)
        • 백엔드 (22)
        • 논리회로 (5)
        • 언어구현 (1)
        • 인공지능 (1)
        • 코드설계 (3)
        • 컴퓨터구조 (9)
        • 데이터베이스 (4)
        • 컴퓨터 네트워크 (10)
      • 언어공부 (65)
        • Java | Kotlin (49)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • [2026] 순수자바로 개발하기 (0)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 놀이터 (0)
      • 에러 수정일지 (4)
      • 고찰 (35)
        • CEOS 23기 회고록 (9)
  • 링크

    • 교양있는컬러잇
  • 최근 글

  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.5
컬러잇
[DB] 정규화
상단으로

티스토리툴바