보편적으로 관계형 데이터베이스의 테이블이 제3정규화(3NF)가 되었으면 정규화 되었다라고 한다. 3정규화된 테이블의 대부분이 삽입, 변경, 삭제 이상이 없으며, 일반적으로 BCNF, 4NF, 5NF를 만족하기 때문에. 정규화되었다고 판단한다. (6NF는 X)
표준 가이드에 따르면 데이터베이스가 완전히 정규화 되게 디자인되어야 한다고 되어있으나, 실제로는 성능상의 문제나 자원적인 문제로 인해서 3NF정도까지 포커스하는 편이므로 우선 그정도 수준까지만 학습했다.
제1정규화 (1NF; First Normal Form)
테이블의 컬럼이 원자값(하나의 값)을 갖도록 테이블을 분해하는 것. (중복제거)
다음의 테이블들을 제1정규화가 되지 않은 상태이다.
Customer ID | First Name | Surname | Telephone Numbers |
---|---|---|---|
123 | Robert | Ingram | 555-861-2025 |
456 | Jane | Wright | 555-403-1659, 555-776-4100 |
789 | Maria | Fernandez | 555-808-9633 |
전화번호의 열이 의미상으로 모호해졌다.
(전화번호를 표현할 수도, 전화번호들의 리스트를 표현할 수도 있다.)
"어떤 고객들이 같은 전화번호를 공유하는가"와 같은 query는 답하기 어려워 졌고,
RDBMS 내에서 전화번호에 대한 의미적인 제한을 정의하는 것 또한 어려워 졌다.
Customer ID | First Name | Surname | Tel.No.1 | Tel.No.2 | Tel.No.3 |
---|---|---|---|---|---|
123 | Robert | Ingram | 555-861-2025 | ||
456 | Jane | Wright | 555-403-1659 | 555-776-4100 | 555-403-1659 |
789 | Maria | Fernandez | 555-808-9633 |
마찬가지로 테이블 질의시 어려움이 있다.
("어느 고객이 전화번호 X를 가지고 있는가?", "어떤 고객들끼리 같은 전화번호를 공유하는가?" 질의들은 답하기 어렵다.)
RDBMS에서 고객-전화번호의 유일성을 확보하기 어렵다. = Tel.No.1과 Tel.No.3에 같은 값이 들어가버릴 수 있다.
전화번호가 3개가 넘는 경우에 제한이 생긴다.
위의 테이블예시를 다음과 같이 1NF를 충족시킬 수 있다.
Customer ID | First Name | Surname |
---|---|---|
123 | Robert | Ingram |
456 | Jane | Wright |
789 | Maria | Fernandez |
.
Customer ID | Telephone Number |
---|---|
123 | 555-861-2025 |
456 | 555-403-1659 |
456 | 555-776-4100 |
789 | 555-808-9633 |
제2정규화 (2NF; Second Normal Form)
제1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해
완전 함수 종속 : 기본키의 부분집합이 결정자가 되어선 안된다는 것을 의미
다른표현으로
후보키 K와 K에 속하지 않는 속성 A가 있을 때, A를 결정하기 위해 K의 일부가 아닌 K 전체를 참조해야만 하는 경우 1NF 테이블은 2NF이다.
다음과 같은 테이블이 있다.
종업원 | 기술 | 근무지 |
---|---|---|
Jones | Typing | 114 Main Street |
Jones | Shorthand | 114 Main Street |
Jones | Whittling | 114 Main Street |
Bravo | Light Cleaning | 73 Industrial Way |
Ellis | Alchemy | 73 Industrial Way |
Ellis | Flying | 73 Industrial Way |
Harrison | Light Cleaning | 73 Industrial Way |
종업원
이나 기술
은 둘다 이 테이블의 후보키(식별자)는 아니다. 종업원
은 다수의 기술을 가지고 있으면 테이블에 한 차례 이상 나타나기 때문이고, 기술
또한 다수의 종업원이 같은 기술을 보유하고 있을때 테이블에 한 차례 이상 나타나기 때문이다. 오직 복합 키 종업원, 기술
이 이 테이블의 후보키이다.
그런데 남은 속성인 근무지
는 후보 키의 일부분인 종업원
에만 영향을 받는다. 그래서 이 테이블은 2NF가 아니다.
근무지
에 중복이 있다는 점을 주목하면,
Jones : 114 Main Street = 3번의 중복
Ellis : 73 Industrial Way = 2번의 중복
이 중복은 테이블을 취약하게 만들며 갱신이상의 원인이 된다. (데이터가 변경될 때 문제가 생김)
예를 들어 Jones의 근무지를 변경시에 "Typing" 과 "Shorthand" 레코드는 변경했는데 "Whittling" 레코드는 변경하지 않았다고 하자. 이럴 경우 "Jones 의 근무지는 어디인가" 질의에 혼동된 답을 얻게 될 것이다.
이 디자인을 2NF로 표현하는 방법은 같은 데이터를 2개의 테이블로 표현하는 것이다
종업원
후보 키를 갖는 "종업원" 테이블과 종업원,기술
후보 키를 갖는 "종업원의 기술" 테이블이다.
종업원 | 근무지 |
---|---|
Jones | 114 Main Street |
Bravo | 73 Industrial Way |
Ellis | 73 Industrial Way |
Harrison | 73 Industrial Way |
.
종업원 | 기술 |
---|---|
Jones | Typing |
Jones | Shorthand |
Jones | Whittling |
Bravo | Light Cleaning |
Ellis | Alchemy |
Ellis | Flying |
Harrison | Light Cleaning |
위와 같이 분리하면 더이상 갱신이상은 발생하지 않는다.
다만, 모든 2NF이 갱신이상이 없는 것은 아니다.
제3정규화 (3NF; Third Normal Form)
제2정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것
이행적 종속 : A -> B, B -> C가 성립할 때 A -> C가 성립되는 것을 의미
아래의 테이블은 2NF이지만 3NF는 아니다.
대회 & 연도
-> 우승자
, 우승자
-> 생년월일
= 대회 & 연도
->생년월일
대회 | 연도 | 우승자 | 우승자 생년 월일 |
---|---|---|---|
Des Moines Masters | 1998 | Chip Masterson | 14 March 1977 |
Indiana Invitational | 1998 | Al Fredrickson | 21 July 1975 |
Cleveland Open | 1999 | Bob Albertson | 28 September 1968 |
Des Moines Masters | 1999 | Al Fredrickson | 21 July 1975 |
Indiana Invitational | 1999 | Chip Masterson | 14 March 1977 |
이를 3NF를 적용하면 다음과 같다.
대회 | 연도 | 우승자 |
---|---|---|
Des Moines Masters | 1998 | Chip Masterson |
Indiana Invitational | 1998 | Al Fredrickson |
Cleveland Open | 1999 | Bob Albertson |
Des Moines Masters | 1999 | Al Fredrickson |
Indiana Invitational | 1999 | Chip Masterson |
.
우승자 | 우승자 생년 월일 |
---|---|
Chip Masterson | 14 March 1977 |
Al Fredrickson | 21 July 1975 |
Bob Albertson | 28 September 1968 |
제1정규화
모든 컬럼은 반드시 하나의 값만 가져야 한다.(원자성)
같은 타입의 데이터가 들어갈 떄는 컬럼을 추가하는 것처럼 테이블 구조를 변경해서는 안 된다.
제2정규화
기본키의 부분집합이 결정자가 되면 안된다. (완전 함수 종속)
후보키에 속하지 않는 속성이 후보키의 부분집합에 의해서 구별되서는 안된다. (전체를 참조)
제3 정규화
이행적 종속을 제거하자. (이행적 종속 : A->B, B->C 일 때, A->C가 성립하는 경우)
Reference:
https://mangkyu.tistory.com/110
https://bruno-jang.tistory.com/45?category=1012953
https://ko.wikipedia.org (데이터베이스_정규화)