하나의 테이블에 다양한 애트리뷰트를 혼합해서 사용한다면 데이터가 중복해서 저장될 수 있고, 이는 다양한 갱신 이상을 발생시킨다.
- 삽입 이상 : 원하지 않는 데이터가 삽입 되거나 필수적으로 삽입할 데이터가 부족해 삽입이 되지 않는 문제 현상을 말한다.
- 삭제 이상 : 하나의 데이터만 삭제하고 싶지만, 해당 데이터 전체가 포함된 튜플이 삭제됨으로써 원하지 않는 데이터가 삭제 되는 문제 현상을 말한다.
- 수정 이상 : 튜플의 일부분만 수정되어 데이터의 의미가 모호해지거나 일관성이 사라지는 문제 현상을 말한다.
정규화(Normalization)의 기본 목적은 테이블 간 중복 데이터를 최소화 시키는 것이다.
중복 데이터를 최소화 시킴으로써 데이터의 무결성 또한 유지되며 다양한 갱신 이상들을 해결할 수 있다.
그리고, 테이블이 구조화 되기 때문에 테이블의 구성을 보다 논리적이고 직관적으로 만들 수 있다.
중복 데이터가 허용되지 않음으로써 데이터의 무결성 또한 유지되며 테이블 구성을 논리적이고 직관적으로 만들 수 있다.
정규화는 테이블을 분해하는 방법에 따라 단계가 나눠진다.
제 1정규화를 시작으로 제 5정규화 까지 단계가 구분되지만 일반적으로는 제 3정규화 혹은 제 3정규화 다음 단계인 BCNF 정규화 단계까지 거친다.
제 1 정규화
제 1정규화는 테이블 컬럼이 원자값(하나의 값)을 갖도록 분리하는 것이다.
아래 OTT 서비스와 컨텐츠를 가진 테이블을 보자. 각 서비스는 다양한 컨텐츠를 포함하고 있지만, 테이블 컬럼이 하나의 값을 갖고 있지 않다.
OTT 서비스 | 컨텐츠 |
넷플릭스 | 기묘한 이야기, 프렌즈 |
왓챠 | 좋좋소, 빅뱅이론 |
디즈니 플러스 | 어벤져스, 문나이트 |
따라서 위의 테이블을 제 1정규화를 통해 구조화 시키면 아래와 같다.
OTT 서비스 | 컨텐츠 |
넷플릭스 | 기묘한 이야기 |
넷플릭스 | 프렌즈 |
왓챠 | 좋좋소 |
왓챠 | 빅뱅이론 |
디즈니 플러스 | 어벤져스 |
디즈니 플러스 | 문나이트 |
제 1정규화를 통해 구조화된 테이블은 모든 컬럼이 하나의 값으로 구분되어 지는 것을 알 수있다.
제 2 정규화
제 2 정규화는 제 1 정규화를 통해 구조화된 테이블을 완전 함수 종속하도록 만드는 것이다. 즉 부분 함수 종속을 제거하는 것이다.
함수적 종속 : X의 값에 따라 Y의 값이 결정될 때 Y는 X에 대해 함수적 종속이라고 표현한다.
완전 함수 종속 : {X1, X2}가 하나의 기본키일 때 Y를 결정하는 경우를 완전 함수 종속이라 한다.
부분 함수 종속 : {X1, X2} 기본키이지만 둘 중 한개만으로도 Y를 결정할 수 있다면 이는 부분 함수 종속이라고 한다.
즉, 기본키가 복합키인 경우 복합키의 부분 컬럼이 다른 컬럼을 결정할 수 있다면, 이는 완전 함수 종속이 아님을 뜻한다. 아래 테이블을 통해 예시를 보자.
이름 | OTT 서비스 | 컨텐츠 | 가격 |
Zayson | 넷플릭스 | 기묘한 이야기 | 3500 |
Haverts | 넷플릭스 | 슈츠 | 3500 |
Kane | 왓챠 | 좋좋소 | 4000 |
Durant | 디즈니 플러스 | 심슨 | 5000 |
Zayson | 디즈니 플러스 | 문나이트 | 5000 |
현재 테이블의 기본키는 (이름, OTT 서비스) 로 이뤄진 복합키이다. 이 복합키를 이용해 “컨텐츠"를 결정할 수 있기 때문에 완전 함수 종속을 만족한다.
하지만 "가격"은 복합키인 (이름, OTT 서비스)가 아닌 OTT 서비스로 구분하는 것이 가능하다. 즉 부분 함수 종속이다.
따라서, 현재 테이블을 (이름, OTT 서비스)로 “컨텐츠”를 결정할 수 있기 때문에 테이블을 제 2 정규화하여 분리시키는 것이 가능하다.
제 2 정규화를 진행한 테이블은 아래와 같다.
이름 | OTT 서비스 | 컨텐츠 |
Zayson | 넷플릭스 | 기묘한 이야기 |
Haverts | 넷플릭스 | 슈츠 |
Kane | 왓챠 | 좋좋소 |
Durant | 디즈니 플러스 | 심슨 |
Zayson | 디즈니 플러스 | 문나이트 |
OTT 서비스 | 가격 |
넷플릭스 | 3500 |
왓챠 | 4000 |
디즈니 플러스 | 5000 |
제 2 정규화를 통해 첫 번째 테이블은 (이름, OTT 서비스)를 기본키로 갖고 콘텐츠를 결정할 수 있으므로 완전 함수 종속을 만족한다.
두 번째 테이블 또한 복합키로 인해 부분 함수 종속이던 테이블을 OTT 서비스를 기본키로 갖게 하여 가격을 결정할 수 있는 완전 함수 종속 테이블로 구분했다.
제 3 정규화
제 3 정규화는 제 2 정규화를 통해 구조화된 테이블의 이행적 종속을 제거하는 것이다.
이행적 종속 : A → B, B → C 이면 A → C일 때 이행적 종속을 의미한다.
아래 테이블은 이름을 기본키로 갖고, 이름을 통해 사용 중인 OTT 서비스와 가격을 결정할 수 있기 때문에 제 2 정규화를 거친 테이블이라고 할 수 있다.
이름 | OTT 서비스 | 가격 |
Zayson | 넷플릭스 | 3500 |
Haverts | 넷플릭스 | 3500 |
Kane | 왓챠 | 4000 |
Durant | 디즈니 플러스 | 5000 |
James | 디즈니 플러스 | 5000 |
테이블에서는 “Haverts” → “넷플릭스", “넷플릭스" → “3500”이고, “Haverts” → “3500”인 이행적 종속 상태이다.
만약 Haverts가 OTT 서비스를 넷플릭스에서 디즈니 플러스로 변경하고자 한다면 가격 또한 함께 변경되어야 문제가 없다.
이름 | OTT 서비스 |
Zayson | 넷플릭스 |
Haverts | 넷플릭스 |
Kane | 왓챠 |
Durant | 디즈니 플러스 |
James | 디즈니 플러스 |
OTT 서비스 | 가격 |
넷플릭스 | 3500 |
왓챠 | 4000 |
디즈니 플러스 | 5000 |
위와 같이 제 3 정규화를 진행하면 OTT 서비스를 변경하더라도 OTT 서비스를 이용해 참조하는 가격을 찾아올 수 있다.
즉 제 3정규화된 테이블은 기본키를 제외한 모든 속성들이 기본키에 의존한다고도 할 수 있다.
BCNF(Boyce - Codd) 정규화
BCNF 정규화는 제 3 정규화 테이블을 조금 더 강화한 형태라고 보면된다. 그래서 BCNF 정규화를 Strong 3NF라고도 부른다.
제 3 정규화 조건을 충족하고 테이블의 결정자가 반드시 테이블의 후보키에 포함되어야 한다.
아래의 테이블은 (이름, 콘텐츠)를 기본키로 갖는 테이블이다.
이름 | 컨텐츠 | OTT 서비스 |
Zayson | 기묘한 이야기 | 넷플릭스 |
Haverts | 기묘한 이야기 | 넷플릭스 |
Kane | 좋좋소 | 왓챠 |
Zayson | 심슨 | 디즈니 플러스 |
(이름, 콘텐츠)가 OTT 서비스를 결정하고 있음을 알 수 있다.
하지만 테이블을 자세히 보면 OTT 서비스 컬럼이 콘텐츠를 결정할 수 있는 것을 알 수 있다.
이 경우, OTT 서비스는 후보키에 포함되고 있지 않지만 콘텐츠를 결정할 수 있기 때문에 BCNF 정규화 조건에 위배된다.
위 테이블을 BCNF 정규화를 진행하면 아래와 같다.
이름 | OTT 서비스 |
Zayson | 넷플릭스 |
Haverts | 넷플릭스 |
Kane | 왓챠 |
Zayson | 디즈니 플러스 |
OTT 서비스 | 컨텐츠 |
넷플릭스 | 기묘한 이야기 |
왓챠 | 좋좋소 |
디즈니 플러스 | 심슨 |
첫 번째 테이블은 (이름, OTT 서비스)를 키로 갖는 테이블이고, 두 번째 테이블은 OTT 서비스를 키로 갖는 테이블이다.
각각의 테이블은 키이면서 결정자의 역할을 하고 있기 때문에 BCNF 정규화 조건을 충족한다.
📄 References
[Database] 정규화(Normalization) 쉽게 이해하기 : https://mangkyu.tistory.com/110
데이터베이스 정규화 - BCNF : https://yaboong.github.io/database/2018/03/10/database-normalization-2/
'Computer Science > DB' 카테고리의 다른 글
SQL과 관계형 모델 (정규화) (DB 스터디 3주차) (0) | 2022.09.28 |
---|---|
술어논리와 관계형 모델 (DB 스터디 2주차) (0) | 2022.09.21 |
SQL과 관계형 모델 (DB 스터디 1주차) (0) | 2022.09.16 |
반정규화 (De-Normalization) (0) | 2022.06.25 |
인덱스(Index) (0) | 2022.06.09 |