정규형(Normal Form, NF)은 데이터 이상(Anomaly) 현상을 제거하기 위한 관계형 모델의 설계 지침입니다.
1, 2, 3 정규형(NF)은 관계형 데이터 모델을 만든 에드거 F. 커드(E.F. Codd) 박사가 제안했습니다.
정규화(Normalization)는 정규형을 위배한 릴레이션을 정규형으로 만드는 과정입니다.
1정규형(1NF), 2정규형(2NF), 3정규형(3NF) 각각에서 만족해야 하는 규칙은 아래 표와 같습니다.
구분 | 조건 |
1정규형 (1NF) | 속성의 원자성(Atomicity) 만족 |
2정규형 (2NF) | 1정규형 만족 + 부분 종속 (Partial dependency) 제거 |
3정규형 (3NF) | 1, 2정규형 만족 + 이행 종속 (Transitive dependency) 제거 |
속성의 원자성, 부분 종속, 이행 종속이라는 용어가 낯설 수 있는데 아래에 예와 함께 풀어서 설명했으니 읽어보시면 좋을 것 같습니다.
속성의 원자성은 DB 테이블의 1개 컬럼에는 1개 정보만 들어가야 한다는 내용입니다.
예를 들어 아래 테이블과 같이 '수강_수업_이름'이라는 컬럼에 '국어, 영어, 수학' 이렇게 3개 정보가 동시에 들어가 있으면 이는 속성의 원자성을 위배하는 것입니다.
학생_이름 | 수강_수업_이름 |
홍길동 | 국어, 수학, 영어 |
박지원 | 영어, 과학 |
홍상직 | 사회, 체육 |
위와 같은 경우'수강_수업_목록'이라는 별도 테이블을 만들어 속성의 원자성 문제를 해결할 수 있습니다.
부분 종속이란 일반 속성이 식별자의 일부 속성에만 종속되는 것입니다.
말로는 이해가 어려울 수 있어 아래 테이블을 예로 들어 설명드리겠습니다.
아래 테이블의 식별자(Key)는 '학생_학번' 컬럼과 '수업_코드' 컬럼이 결합된 Super key입니다
학생_학번(PK) | 수업_코드(PK) | 수업_명 (부분 종속 예시) | 수업_성적_코드 (완전 종속) |
1001 | 2000 | 국어 | A |
1001 | 2001 | 수학 | A |
1001 | 2002 | 영어 | B |
1002 | 2001 | 수학 | B |
1002 | 2002 | 영어 | A |
식별자를 제외한 일반 속성 '수업_명', '수업_성적' 컬럼이 부분 종속인지 완전 종속인지 확인해보겠습니다.
위와 같은 경우에는 부분 종속인 수업_명 컬럼을 별도 테이블로 나눠 부분 종속 문제를 해결해야 2정규형을 만족하게 됩니다.
이행 종속이란 일반 속성이 다른 일반 속성에 종속되는 것입니다.
이번에도 말로는 이해가 어려울 수 있어 아래 테이블을 예로 들어 설명드리겠습니다.
아래 테이블은 2정규형을 만족하는 테이블입니다.
하지만 일반 속성인 '수업_성적_코드'에 '수업_성적_평점'이 종속되는 이행 종속 문제를 가지고 있습니다.
학생_학번(PK) | 수업_코드(PK) | 수업_성적_코드 | 수업_성적_평점 |
1001 | 2000 | A | 4.3 |
1001 | 2001 | A | 4.3 |
1001 | 2002 | B | 3.3 |
1002 | 2001 | B | 3.3 |
1002 | 2002 | A | 4.3 |
이행 종속 문제를 해결하여 제3정규형을 만족하려면 수업_평점을 관리하는 별도 테이블을 생성해야 합니다.
이번 포스팅에서는 제1정규형, 2정규형, 3정규형이 무엇인지와 조건에 대한 예시를 알아봤습니다.
다음번에는 예시 테이블로 정규화를 진행해 보겠습니다.
기타 궁금하신 사항은 댓글 남겨주세요.
감사합니다.
1. 정희락, 불친절한 SQL 프로그래밍 22p~24p, 데비안(2018)
1. 데카의 데일리 리뷰, [DB 모델링- 3.정규화 : 3.5 정규형의 종류], https://pronician.tistory.com/922
2. Deep Play님 블로그, [데이터베이스 정규화 1NF, 2NF, 3NF, BCNF, https://3months.tistory.com/193
[SQL 실행과정] 파싱(Parsing), 소프트파싱(Soft parsing), 하드 파싱(Hard parsing) - SQL 쿼리 처리 과정 (0) | 2021.04.18 |
---|---|
[Oracle DB] 오라클 DB 백그라운드 프로세스별 역할 (0) | 2021.04.18 |
[Oracle] 연속으로 된 날짜 만들기 (CONNECT BY LEVEL 활용) (1) | 2021.03.31 |
[Oracle] 오라클 VARCHAR2 타입 Byte semantics과 Character Semantics (0) | 2021.03.09 |
[MySQL] 날짜 형식이 섞여있는 데이터 처리 하기 (0) | 2021.02.14 |