DB 정규화 (제 1정규형 ~ 제 3정규형, BCNF)
DB 정규화(제 1정규형 ~ 제 3정규형, BCNF)에 대해 알아보겠습니다.
정규화(Normalization)란?
정규화는 이상현상이 있는 테이블을 기준에 따라 여러개로 나누어 이상현상을 없애는 작업을 말합니다.
이상현상(Anomaly)이란?
이상현상은 세 종류가 있습니다.
- 삽입 이상: 행(row) 삽입시 특정 컬럼(column)에 해당하는 값이 없어 null을 입력하는 현상
- 수정 이상: 행 수정시 중복된 데이터의 일부만 수정되는 데이터 불일치 현상
- 삭제 이상: 행 삭제시 같이 저장된 다른 정보까지 삭제되는 현상
예시를 통해 자세히 알아보겠습니다.
삽입 이상
'자이언츠'라는 작품을 추가한다고 가정해보겠습니다. 자이언츠의 작가는 작품 설명을 따로 등록하고 싶지 않아 작품 설명을 적지 않았습니다. 이 경우 위 테이블에서 작품 설명 칸에는 null 값이 들어가는 삽입 이상 현상이 발생합니다.
수정 이상
'대림킴' 작가는 작가 활동명을 '소림킴'으로 바꾸고 싶어 합니다. 이 경우 작가 활동명을 대림이나 한화이글스 중 한 부분만 수정하면 다른 부분에서 작품 이름과 작가 활동명이 일치하지 않는 수정 이상 현상이 발생합니다.
삭제 이상
관리자가 '신도림' 작품의 작품 설명을 삭제하려 합니다. 이 경우 해당 작품의 작품 설명 데이터만 삭제하는 것이 아니라 한 행을 삭제해야하는 삭제 이상 현상이 발생합니다.
위 예시와 같은 이상 현상을 방지하기 위해 아래와 같은 순서로 정규화를 진행합니다.
제 1 정규화
제 1 정규화는 테이블의 모든 컬럼 값이 원자 값을 갖도록 테이블을 나누는 것입니다.
위와 같이 한 컬럼 값으로 여러 데이터가 들어가있는 경우 아래와 같이 행을 분리할 수 있습니다.
제 2 정규화
제 2 정규화는 제 1 정규형을 만족하는 테이블에 대해 모든 컬럼이 완전 함수 종속을 만족할 때 까지 나누는 것입니다. 완전 함수 종속이란 테이블 내 특정 속성이 기본키에 대해 완전히 종속적인 것을 의미합니다.
위는 웹툰 평점 테이블 입니다. 이 테이블에서 기본키는 유저 아이디와 작품 이름으로 복합키입니다. 그리고 유저 아이디와 작품 이름이 평점을 결정하고 있습니다. 그러나 작가 활동명의 경우 기본키의 부분 집합인 작품 이름에 따라 결정되고 있습니다. 따라서 기본키의 부분 집합인 작품 이름이 결정자이기 때문에 제 2 정규화 대상입니다. 위 테이블은 아래와 같이 분리할 수 있습니다.
제 3 정규화
제 3 정규화는 제 2정규형을 만족하는 테이블에 대해 이행적 종속을 없애도록 테이블을 나누는 것입니다. 이행적 종속이란 A -> B, B -> C가 성립할 때 A -> C가 성립하는 것을 의미합니다.
위는 등급별 할인 혜택 테이블 입니다. 유저는 활동에 따른 등급을 가지고, 각각의 등급은 혜택으로 할인율을 가집니다. 따라서 유저 아이디 -> 할인율이 성립하는 이행적 종속이 발생하기 때문에 제 3 정규화 대상입니다. 위 테이블은 아래와 같이 분리할 수 있습니다.
BCNF 정규화
BCNF 정규화는 제 3 정규형을 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 테이블을 나누는 것 입니다. 즉 테이블 내의 다른 컬럼 값을 고유하게 결정짓는 컬럼이 유일하고 최소한의 값만 가진 식별자가 되도록 테이블을 나누는 것입니다.
위 예시는 작품 구매 테이블로 한 작가가 한 작품만 판매할 수 있다는 가정하에 진행됩니다. 위 테이블에서 유저 아이디와 작품 이름으로 작가를 결정할 수 있고, 유저 아이디와 작가로 작품 이름을 결정할 수 있습니다. 따라서 둘 다 후보키이기 때문에 하나를 기본키로 설정하여 아래와 같이 분리할 수 있습니다.
실무에서는 일반적으로 BCNF 정규화까지만 진행한다고 합니다. 이 단계까지 정규화를 진행하면 대부분의 이상현상을 방지할 수 있으며 테이블을 나누어 얻는 실익이 줄어들기 때문입니다.
* 최대한 적합한 예시를 들려했으나 부적절한 예시일 수 있습니다. 이에 본 글에 문제가 있다면 좋은 의견 및 조언 부탁드립니다.