한 릴레이션에 여러 엔티티의 애트리뷰트들을 혼합하게 되면 정보가 중복 저장되며, 저장 공간을 낭비하게 됨
✔️ 중복된 정보의 문제점 : 한 릴레이션에서는 변경하고, 나머지 릴레이션에서는 변경하지 않은 경우 어느 것이 정확한지 알 수 없음 등의 문제가 발생 -> 이상 발생
이러한 문제를 해결하기 위해 정규화 과정을 거치는 것
함수적 종속성 등의 종속성 이론을 이용하여 잘못 설계된 관계형 스키마를 더 작은 속성의 세트로 쪼개어 바람직한 스키마로 만들어 가는 과정
엔티티를 구성하고 있는 애트리뷰트 간에 함수적 종속성(Functional Dependency)을 판단한다.
즉, 각각의 정규형마다 어떠한 함수적 종속성을 만족하는지에 따라 정규형이 정의되고, 그 정규형을 만족하지 못하는 정규형을 나쁜 릴레이션으로 파악함
함수적 종속성이란 데이터들이 어떤 기준값에 의해 종속되는 것을 의미함
X와 Y를 임의의 애트리뷰트 집합이라고 할 때, X의 값이 Y의 값을 유일하게 결정한다면, X는 Y를 함수적으로 결정한다.라고 함
💡 예를 들어,
<수강> 릴레이션이 (학번, 이름, 과목명)으로 되어 있을 때, '학번'이 결정되면 '과목명'에 상관없이 '학번'에는 항상 같은 '이름'이 대응된다.
'학번'에 따라 '이름'이 결정될 때 '이름'을 '학번'에 함수 종속적이라고 하며, '학번->이름'과 같이 씀
정규화의 목적은
✔️ 불필요한 데이터를 제거해서 불필요한 중복 최소화 하기
✔️ 각종 이상 현상 방지하기
이렇게 중복된 데이터를 허용하지 않음으로서 무결성을 유지할 수 있고 디스크의 저장 효율 역시 높일 수 있다 !
그래서, 정규화를 하기 위해서는 함수적 종속성과 같은 이론을 따라 분해한다 !
✔️ 각 정규형은 그 선행 정규형의 조건도 지켜야 한다
테이블의 컬럼이 원자값(Atomic Value, 하나의 값)을 갖도록 테이블을 분해
위의 그림에서 보면 수경이와 준헌이는 취미가 두개라서 제 1정규형을 만족하지 ❌
따라서 이를 제1 정규화하여 오른쪽 그림과 같이 분해할 수 있는 것
완전 함수적 종속을 만족하도록 테이블을 분해
완전 함수적 종속 이면 제 2 정규형을 만족 -> 부분적 함수 종속을 제거해야 함
✔️ 완전 함수적 종속이란
X -> Y 라고 가정했을 때, X의 어떤 애트리뷰트라도 제거하면 더 이상 함수적 종속성이 성립하지 않는 경우
위의 수강강좌 테이블을 보자
즉, 기본키인 (학생번호, 강좌이름)
의 부분키인 강좌이름
이 결정자이기 때문에 위의 테이블의 경우 다음과 같이 기존의 테이블에서 강의실을 분해하여 별도의 테이블로 관리하면 제2 정규형을 만족시킬 수 있다.
이행적 종속을 없애도록 테이블을 분해
어떤 애트리뷰트도 기본키에 대해 이행적 함수 종속되지 않으면 제 3 정규형을 만족한다고 볼 수 있음 -> 이행적 함수 종속을 제거해야 함
✔️ 이행적 함수 종속이란
X -> Y, Y -> Z의 경우에 의해서 추론될 수 있는 X -> Z의 종속관계를 말함
위의 계절학기 테이블을 보자
즉, 위와 같이 학생 번호를 통해 강좌 이름을 참조하고, 강좌 이름으로 수강료를 참조하도록 테이블을 분해해야 함
모든 결정자가 후보키가 되도록 테이블을 분해하는 것
여러 후보 키가 존재하는 릴레이션에 해당하는 정규화 내용임. 제 3 정규형을 보완하는 데 의미가 있음 -> 결정자이면서 후보키가 아닌 것을 제거
위의 특강 테이블을 보자
그런데 문제는 교수가 특강이름을 결정하는 결정자이지만, 후보키가 아니라는 점이다. 그렇기 때문에 BCNF 정규화를 만족시키기 위해서 위의 테이블을 분해해야 함
관계 데이터베이스 설계의 목표는 각 릴레이션이 3NF or BCNF 를 갖게 하는 것
=> 실무에서는 대체로 1~3 정규화까지 한다고 함
릴레이션의 분해로 인해 릴레이션 간의 조인 연산이 많아짐. 이로 인해 질의에 대한 응답 시간이 느려질 수 있음.
조회를 하는 SQL 문장에서 조인이 많이 발생해서 성능 저하가 일어나면 반정규화를 적용
반정규화는 시스템의 성능 향상, 개발 및 운영의 편의성 등을 위해 정규화된 데이터 모델을 통합, 중복, 분리하는 과정으로, 의도적으로 정규화 원칙을 위배하는 행위임
1. 테이블 통합 : 두 개의 테이블이 조인되는 경우가 많아 하나의 테이블로 합쳐 사용하는 것이 성능 향상에 도움이 될 경우 수행
2. 테이블 분할 : 테이블을 수직 또는 수평으로 분할하는 것
3. 중복 테이블 추가 : 여러 테이블에서 데이터를 추출해서 사용해야 하거나 다른 서버에 저장된 테이블을 이용해야 하는 경우 중복 테이블을 추가하여 작업의 효율성 향상 가능
4. 중복 속성 추가 : 조인해서 데이터를 처리할 때 데이터를 조회하는 경로를 단축하기 위해 자주 사용하는 속성을 하나 더 추가하는 것
데이터의 무결성이 깨질 수도 있고, 성능이 더 저하될 수도 있음
✔️ 정규화 : 온라인 거래 시스템 같은 OLTP(OnLine Transaction Processing) 데이터베이스는 CRUD(Create, Read, Update, Delete) 가 많이 일어나 정규화가 적절하다.
✔️ 반정규화 : 분석 리포트 같은 OLAP(OnLine Analytical Processing) 데이터베이스는 분석과 리포팅을 위해 사용되기 때문에 연산의 속도를 위해 반정규화를 사용하는 게 좋습니다.
참조 : https://mangkyu.tistory.com/110
https://velog.io/@wldus9503/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%A0%95%EA%B7%9C%ED%99%94Normalization%EB%9E%80