티스토리 뷰

DB

정규화의 정의와 3.5정규형까지

Jaehee Jeon 2022. 8. 30. 21:16
반응형

정규화(Normalization)의 정의와 목적

 

 하나의 테이블에 모든 정보를 저장하면 필연적으로 동일한 내용의 중복이 많아지게 된다. 중복이 많아짐은 저장 공간의 낭비는 물론이고, 삽입/삭제/갱신과 관련된 데이터베이스 이상 현상(Anomaly)이 발생하기도 쉬워진다. 데이터베이스 정규화(Normalization)는 관계형 데이터베이스를 설계할 때 중복이 최소화되도록 데이터를 구조화하는 과정을 의미한다.

 정규화 과정은 제1 정규형에서 제5 정규형까지 존재하며, 상위의 정규형은 하위 정규형의 조건을 모두 만족한다. 이 글에서는 제3 정규형과 3.5 정규형으로 불리는 보이스-코드 정규형(Boyce-Codd normal form, BCNF)까지의 과정을 다룬다.

 

 

정규화되지 않은 비정규 릴레이션

 

상품 번호 상품 명 분류 판매 일자 구매자
100 선풍기 가전 1/1, 2/1 김, 이
200 두부 식료품 1/2
300 휴지 생필품 1/2
400 콩나물 식료품 1/3

 

 우리가 작은 마트를 운영하고 위와 같이 네 개의 상품에 대한 판매 내역을 하나의 큰 엑셀 테이블에 정리하려고 한다 가정하자. 이 테이블은 정규화가 전혀 이루어지지 않은 '비정규 릴레이션'이라 하며, 추후 데이터를 삽입/삭제/갱신하려 할 때 불필요한 이상 현상이 발생하게 된다.

 예를 들어,  더 이상 선풍기를 판매하지 않게 되었을 때, 사용하는 테이블이 하나뿐이므로 선풍기가 기재된 첫 번째 행을 삭제하면 두 건의 구매 이력도 함께 사라지게 된다.

 위의 테이블에 대한 정규화를 진행하며, 이상 현상들이 발생할 수 있는 상황을 제거해 보자.

 

제1 정규형 

 

 제1 정규형은, "반복되는 속성이 분리되어 모든 속성이 원자값으로만 되어 있는 정규형"이다. 만약 위의 표를 관계형 데이터베이스화한다면 하나의 상품에 대해 여러 주문이 생성되는 경우 'set'과 같은 자료형을 사용하여 여러 주문을 한 셀에 모아 적어야 하는데 이는 다루기에 매우 불편하다. 제1 정규형에선 이를 방지하고자 모든 속성의 속성 값을 원자값으로 바꾼다.

 

상품 번호 상품 명 분류 판매 일자 구매자
100 선풍기 가전 1/1
100 선풍기 가전 2/1
200 두부 식료품 1/2
300 휴지 생필품 1/2
400 콩나물 식료품 1/3

 

 위와 같이 모든 속성 값을 원자화하면 제1 정규화가 진행된 것이다.

 그러나 여전히 가게에 상품을 삭제하면 판매 이력이 사라지고(삭제 이상), 상품을 추가하려면 판매 이력 또한 기재해야 하며(삽입 이상), 상품 중 '선풍기'의 분류를 변경하려면 모든 '선풍기'에 관한 행을 함께 수정해주어야 한다.(갱신 이상)

 

 

제2 정규형

 

 제1 정규형의 문제점을 해소하기 위해 속성 간의 '부분함수적 종속' 관계를 제거하여 '완전함수적 종속' 관계만을 가지는 릴레이션으로 분리시킨 것이 제2 정규형이다.

 

부분함수적 종속

 제1 정규화된 테이블의 속성 간 관계를 살펴보자. 기존의 테이블에서 하나의 행을 특정하기 위해서는 '상품 번호'와 '판매 일자'를 복합키로 사용하여야 한다.

 

 상품에 대한 '구매자' 속성을 알기 위해서는 '상품 번호'와 '판매 일자' 두 개의 복합키를 모두 알아야 하나,

속성 중 '상품 명'과 '분류' 속성은 '상품 번호'만 알아도 특정할 수 있다.

 따라서 '구매자' 속성은 이 테이블의 복합키에 대해 완전함수적 종속이나, '상품 명'과 '분류' 속성은 복합키 중 '상품 번호'만으로도 특정이 가능하므로 부분함수적 종속이다.

 

 따라서 부분함수적 종속 관계의 속성을 별도의 릴레이션으로 분리하면 아래의 두 테이블을 얻을 수 있으며, 이것이 제2 정규화가 진행된 모습이다.

 

 

상품 번호 상품 명 분류
100 선풍기 가전
200 두부 식료품
300 휴지 생필품
400 콩나물 식료품

상품 테이블

 

상품 번호 상품 명 구매자
100 선풍기
100 선풍기
200 두부
300 휴지
400 콩나물

판매 이력 테이블

 

 

 정규화 이후 두 테이블은 각각 기본키 또는 복합키와 나머지 속성이 완전함수적 종속 관계이다.

 여전히 이상 현상이 발생하는데, '선풍기' 상품을 더 이상 판매하지 않는다면 '가전' 분류가 통째로 삭제되게 된다(삭제 이상)

 

 

제3 정규형

 

 제3 정규형에서는 제2 정규화된 상태에서 이행함수적 종속관계를 추가적으로 제거한다.

 

이행함수적 종속

 제2 정규화 이후 분리된 상품 테이블을 보면, '상품 번호'를 알면 '상품 명'을 알고, '상품 명'을 알면 다시 '분류'를 알 수 있다. 같은 테이블 내에서 연쇄적으로 속성들을 특정할 수 있는 관계를 이행함수적 종속 관계라 하며, 기본키가 아닌 속성이 다른 속성을 결정하지 않도록 릴레이션을 다시 분리하여 제3 정규형을 완성한다.

 

상품 번호 상품 명
100 선풍기
200 두부
300 휴지
400 콩나물

 

상품 명 분류
선풍기 가전
두부 식료품
휴지 생필품
콩나물 식료품

 

 

보이스-코드 정규형(Boyce-Codd normal form, BCNF)

 

 제3.5 정규형이라고도 불리는 보이스-코드 정규형에서는 제3 정규화에 추가적으로 데이터 중복 문제를 해소한다.

 

구매자 상품 명 배송 주소
휴지 노원구
콩나물 중랑구
선풍기 마포구
두부 강남구
두부 강서구

 

 판매한 상품을 배송하기 위해 판매한 상품의 배송 정보와 관련된 테이블을 위와 같이 구성했다 가정하자. 모든 구매자의 주소는 다르다 가정한다. 모든 속성 값이 원자값이며(제1 정규형), 복합키인 '구매자'와 '상품 명'으로 배송 주소를 특정 가능하므로 완전함수적 종속 상태이고(제2 정규형), 기본키가 아닌 속성이 다른 속성을 결정하지 못하므로(사실 별도의 속성이 없는...) 이행함수적 종속이 없는 제3 정규형 상태이다.

 그러나 특이하게도 복합키로 결정되는 '배송 주소' 속성이, 반대로 복합키의 일부인 '상품 명' 속성을 결정할 수 있다.

예를 들어 강서구로 배송되는 상품은 두부임이 유일하지만, 두부를 배송하는 곳은 강서구로 유일하지는 않다.

 

 BCNF에서는 이렇게 복합키의 일부가 이외의 속성에 종속되는 현상을 제거, 다시 두 개의 릴레이션으로 나눠준다.

 

구매자 상품 명
휴지
콩나물
선풍기
두부
두부

 

배송 주소 상품 명
노원구 휴지
중랑구 콩나물
마포구 선풍기
강남구 두부
강서구 두부

 

 제2 정규형은 복합키의 일부만이 다른 속성을 결정하는 것을 제거하는 것이며, BCNF는 복합키가 아닌 속성에 복합키의 일부가 종속되는 것을 제거한다는 차이를 유의하자.

 

 

정규화는 언제나 좋은가?

 

  이외에도 제4, 제5 정규형이 존재하며 이를 통해 중복을 더 제거하고 이상 현상을 방지할 수 있으나, 특별한 목적이 있지 않은 이상 제3, 제3.5 정규형에서 그친다. 이것은 고급 정규형이 언제나 장점만 가지는 것이 아니기 때문이다. 지나치게 정규화된 릴레이션에서 쿼리에 따라서 매우 많은 조회와 JOIN 연산을 수행하게 되는데 이것이 오히려 성능 병목으로 작용할 수 있다. 따라서 서비스의 특성에 맞게 자주, 혹은 정해진 범위에서 조회되는 테이블의 경우 적절한 반정규화(Denormalization)를 고려함이 적절하다.

반응형