정규화는 여러 단계로 진행되는데, 이를 '정규형'이라고 부르고 1-5 정규화가 있다.
정규형 | 기본 원칙 | 설명 |
---|---|---|
제 1정규화 | 각 컬럼은 유일한 값을 가져야하며, 테이블의 모든 엔트리는 스칼라 값을 가져야 함 | 하나의 컬럼에 여러 값이 들어가지 않도록 해야 한다. |
제 2정규화 | 제 1정규화를 만족하면서, 기본키가 아닌 모든 컬럼이 기본키에 완전히 종속되어야 함 | 부분적인 종속성을 제거한다. 복합키의 경우, 키가 아닌 컬럼이 그 키의 일부에만 종속되는 것을 방지한다. |
제 3정규화 | 제 2정규화를 만족하면서, 기본키가 아닌 모든 컬럼이 기본키에만 의존해야 함 | 이행적 종속성을 제거한다. 기본키가 아닌 컬럼이 다른 컬럼을 통해 간접적으로 기본키에 종속되는 것을 방지한다. |
BCNF | 제 3정규화를 만족하면서, 모든 결정자가 후보키 집합에 속해야 함 | 결정자가 모두 후보키가 되도록 설계된 테이블 형태이다. |
제 4정규화 | BCNF를 만족하면서, 다중 값 종속성을 제거함 | 하나의 속성이 다른 속성에 대해 다중 값 종속성을 가지면, 그 속성들은 별도의 테이블로 분리해야 한다. |
제 5정규화 | 제 4정규화를 만족하면서, 조인 종속성을 제거함 | 어떤 테이블이 그 테이블의 일부분으로 프로젝션된 두 개 이상의 테이블을 조인하여 원래의 테이블과 같이 만들 수 없어야 한다. |
위와 같이 진행되며 보통 1NF ~ 3NF까지 진행하거나 BCNF단계까지 진행한다
각 컬럼은 유일한 값을 가져야 하며, 모든 엔트리는 하나의 값만을 가져야 한다.
예시: 학생이 여러 과목을 수강하는 경우를 생각해 보자
학생이름 | 수강과목 |
---|---|
지수 | 수학, 영어 |
위 테이블은 제1정규형을 만족하지 않는다.
이를 제1정규형에 맞게 수정하면 아래와 같이 작성할 수 있다.
학생이름 | 수강과목 |
---|---|
지수 | 수학 |
지수 | 영어 |
제1정규형을 만족하면서, 기본키가 아닌 모든 컬럼이 기본키에 완전히 종속되어야 한다.
예시: 학생이 여러 과목을 수강하고, 각 과목에는 담당 교수가 있는 경우를 생각해 보자
학생이름 | 수강과목 | 담당교수 |
---|---|---|
지수 | 수학 | 김교수 |
지수 | 영어 | 이교수 |
위 테이블에서 '담당교수' 컬럼은 '수강과목'에 종속되어 있다.
이를 제2정규형에 맞게 수정하면 아래와 같이 작성할 수 있다.
학생-수강과목 테이블:
학생이름 | 수강과목 |
---|---|
지수 | 수학 |
지수 | 영어 |
수강과목-담당교수 테이블:
수강과목 | 담당교수 |
---|---|
수학 | 김교수 |
영어 | 이교수 |
제2정규형을 만족하면서, 기본키가 아닌 모든 컬럼이 기본키에만 의존해야 한다.
예시: 학생이 여러 과목을 수강하고, 각 과목에는 담당 교수가 있으며, 각 교수는 특정 학과에 소속되어 있는 경우를 생각해 보자
학생이름 | 수강과목 | 담당교수 | 교수소속학과 |
---|---|---|---|
지수 | 수학 | 김교수 | 수학과 |
지수 | 영어 | 이교수 | 영어과 |
위 테이블에서 '교수소속학과' 컬럼은 '담당교수'에 종속되어 있다.
이를 제3정규형에 맞게 수정하면 아래와 같이 작성할 수 있다.
학생-수강과목 테이블:
학생이름 | 수강과목 |
---|---|
지수 | 수학 |
지수 | 영어 |
수강과목-담당교수 테이블:
수강과목 | 담당교수 |
---|---|
수학 | 김교수 |
영어 | 이교수 |
담당교수-교수소속학과 테이블:
담당교수 | 교수소속학과 |
---|---|
김교수 | 수학과 |
이교수 | 영어과 |
제3정규형을 만족하면서, 모든 결정자가 후보키 집합에 속해야 한다.
예시:학생이 여러 과목을 수강하고, 각 과목에는 고유한 코드가 있는 경우를 생각해 보자
학생이름 | 수강과목 | 과목코드 |
---|---|---|
지수 | 수학 | MATH101 |
지수 | 영어 | ENG101 |
위 테이블에서 '과목코드'가 '수강과목'을 결정짓고 있다.
이를 BCNF에 맞게 수정하면 아래와 같이 작성할 수 있다.
학생-과목코드 테이블:
학생이름 | 과목코드 |
---|---|
지수 | MATH101 |
지수 | ENG101 |
과목코드-수강과목 테이블:
과목코드 | 수강과목 |
---|---|
MATH101 | 수학 |
ENG101 | 영어 |
BCNF를 만족하면서, 다중 값 종속성을 제거한다.
예시: 학생이 여러 과목을 수강하고, 각 과목마다 복수의 교재를 사용하는 경우를 생각해 보자
학생이름 | 수강과목 | 교재 |
---|---|---|
지수 | 수학 | 교재A, 교재B |
지수 | 영어 | 교재C, 교재D |
위 테이블에서 '교재'는 '수강과목'에 다중 값 종속성을 가지고 있다.
이를 제4정규형에 맞게 수정하면 아래와 같이 작성할 수 있다.
학생-수강과목 테이블:
학생이름 | 수강과목 |
---|---|
지수 | 수학 |
지수 | 영어 |
수강과목-교재 테이블:
수강과목 | 교재 |
---|---|
수학 | 교재A |
수학 | 교재B |
영어 | 교재C |
영어 | 교재D |
4NF를 만족하면서, 조인 종속성을 제거한다.
예시: 학생, 과목, 교수가 있고, 학생이 과목을 수강하며, 과목은 교수에게 교육받을 경우를 생각해 보자
학생이름 | 수강과목 | 담당교수 |
---|---|---|
지수 | 수학 | 김교수 |
지수 | 영어 | 이교수 |
위 테이블에서 학생-수강과목, 수강과목-담당교수를 분리하면 아래와 같이 작성할 수 있다.
학생-수강과목 테이블:
학생이름 | 수강과목 |
---|---|
지수 | 수학 |
지수 | 영어 |
수강과목-담당교수 테이블:
수강과목 | 담당교수 |
---|---|
수학 | 김교수 |
영어 | 이교수 |
하지만 이렇게 분리하면 원래의 정보(지수 학생이 수학 과목을 김교수에게 배운다)를 잃어버리게 된다.
따라서 이 경우에는 테이블 분리를 하지 않는 것이 제5정규형을 만족하는 방법이다.
정규화는 데이터베이스의 중복을 최소화하고 무결성을 보장하는 데 중요하지만, 과도한 정규화는 데이터베이스의 성능을 저하시킬 수 있다. 따라서, 각 상황에 따라 적절한 정규형을 선택하는 것이 중요하다.
빠른 데이터 조회
→ 조인 비용이 줄어들기 때문
살펴볼 테이블이 줄어들기 때문에 데이터 조회 쿼리가 간단해짐
→ 따라서 버그 발생 가능성도 줄어든다
대부분의 대규모 IT 업체의 경우처럼, 규모 확장성(scalability)을 요구하는 시스템의 경우 거의 항상 정규화된 데이터베이스와 비정규화된 데이터베이스를 섞어 사용한다.
비정규화는 성능 향상을 위한 전략이지만, 데이터의 무결성 문제를 초래할 수 있으므로 주의해서 사용해야 한다.
또한, 비정규화를 통해 성능을 향상시키려면 시스템의 전반적인 성능을 이해하고, 쿼리 동작 방식, 사용 패턴 등을 고려해야 한다.
참고 : https://owlyr.tistory.com/20
참고 : https://velog.io/@bsjp400/Database-DB-%EC%A0%95%EA%B7%9C%ED%99%94-%EB%B9%84%EC%A0%95%EA%B7%9C%ED%99%94%EB%9E%80