정규화
- 정규화(Normalization)란 테이블 간 중복된 데이터를 줄이며 데이터 무결성을 개선하기 위해 정규화 단계에 따라 관계형 데이터 베이스를 구조화 하는 과정이다.
- 데이터 무결성이란 데이터의 정확성, 일관성, 유효성이 유지되는 것을 뜻한다.
- 데이터의 정확성: 데이터의 중복이나 누락이 없는 상태.
- 데이터의 일관성: 원인과 결과의 의미가 연속적으로 보장되어 변하지 않는 상태.
- 정규화의 필요성에 대해 더 자세히 알고싶다면 클릭!
- 중복된 데이터 방지, 부모와 자식 데이터 간의 논리적 관계 유지, 에러 감소 및 재개발 비용 감소 등을 위해 존재한다.
- 따라서 이를 해결하기 위해 정규화 라는 과정을 거치며 이는 단계별로 존재한다.
- 단계는 여러가지가 있으며 특정 단계는 그 이전 단계의 조건을 모두 만족시켜야 한다.
- 이 게시글에서는 1NF~3NF까지 설명하며 그 이후 단계인 BCNF는 이곳에서 확인이 가능합니다.
- 보통 3NF나 그 다음단계까지 적용한다고 들었으며, 너무 많은 정규화 작업은 JOIN으로 인해 성능저하를 야기할 수 있다함.
- 정규화는 단계별로 1NF, 2NF, 3NF, BCNF, 4NF, 5NF
- 한칸엔 하나의 데이터만!
- 테이블의 컬럼이 원자값(Atomic value)를 가져야한다.
- 테이블은 반드시 하나 이상의 키를 가지고 있어야 한다.
USER_NO | USER_NAME | PROGRAM |
---|
101 | Kim | Boxing |
102 | Park | Body weight trainning |
103 | Kang | Weight trainning, Boxing |
- 위와 같은 테이블이 있다고 가정하면
USER_NO
가 103번인 Kang이 2개의 운동 프로그램을 가지고있다.
- 이럴경우 복싱을 수강하는 사람을 찾을때 귀찮아지고, 프로그램명 수정도 어려워진다.
WHERE PROGRAM LIKE '%Boxing%'
- 이런식으로 위와같이 쿼리문을 짜야한다.
- 하지만 아래처럼 테이블에 행 자체를 추가해서 한칸에 하나의 데이터를 보관한다면
USER_NO | USER_NAME | PROGRAM |
---|
101 | Kim | Boxing |
102 | Park | Body weight trainning |
103 | Kang | Weight trainning |
103 | Kang | Boxing |
WHERE PROGRAM LIKE 'Boxing'
- 위 과정을 만족하는 테이블을 제1 정규형 테이블이라고 하며 위 과정을 제1 정규화 라고 부르며 원자값, atomic value를 가지고 있다고 한다.
- 제2 정규화란, 제1 정규화를 마친 테이블에 대해, PK가 여러키로 구성된 복합키(composite key)일 경우 2차 정규화의 대상이 된다.
- 복합키 전체에 의존하지 않고 복합키의 일부, 복합키의 부분집합에만 종속되는 속성이 존재할 경우 이를 분리하는 과정이다.
- Partial dependency(부분적 함수 종속 관계)를 제거한 테이블(설명 아래 나옴).
- 관계에서 종속자가 기본키가 아닌 다른 속성에 종속되거나, 복합키의 부분집합중 일부에만 종속되어 있음을 의미함.
- 부분적 함수 종속이 더이상 발생하지 않는다면 이를 완전 함수적 종속이라 칭한다.
USER_NO | Program | Price | Montly payment |
---|
101 | Boxing | $5 | 0 |
102 | Body weight trainning | $7 | 1 |
103 | Weight trainning | $6 | 1 |
103 | Boxing | $5 | 0 |
- 위와 같은 구조의 테이블이 있다고 가정했을때, 특정 운동의 가격을 수정하려고 한다면 가격을 그냥 수정하는 방법이 있다.
- 하지만, 위의 테이블이 훨씬 더 커서 천명, 만명 그 이상의 갯수를 수정해야 하는 경우가 생긴다면 테이블이 클수록 더 비효율적인 과정이 된다.
- 따라서 이를 해결하기 위해
Price
컬럼을 아래와 같이 새로운 테이블을 추가로 만들어 따로 관리해 참조하는 방식으로 한다면, 훨씬 더 효율적으로 만들 수 있다.
USER_NO | Program | Montly payment |
---|
101 | Boxing | 0 |
102 | Body weight trainning | 1 |
103 | Weight trainning | 1 |
103 | Boxing | 0 |
Program | Price |
---|
Boxing | $5 |
Body weight trainning | $7 |
Weight trainning | $6 |
- 이런식으로 위와 같이 프로그램별 가격을 나타내는 테이블을 따로 만들면
USER_NO
의 수가 무수히 많아도 훨씬 효율적으로 관리할 수 있다.
USER_NO
와 Program
두개의 컬럼은 위 테이블에서 composite key(복합키)(composite primary key)라고 불리우며 특정 유저가 월별 요금을 납부했는지를 기록한다.
- 복합키의 부분집합인
Program
컬럼이 해당테이블의 특정 컬럼과의 관계를 못나타내게 해야한다.
- 위의 경우엔
USER_NO
Program
두개의 컬럼으로 이루어진 composite key의 부분집합인 Program
컬럼이 이에 해당하며, Program
별 Price
를 나타내는 테이블을 따로 만들어 관리하면 더욱 효율적으로 관리가 가능하다.
- 추가로
Price
컬럼과 같이 복합키의 부분집합인 Program
컬럼에 종속되는 컬럼을 partial dependency가 있다고 표현한다.
- 따라서 partial dependency가 있는 테이블을 다른 테이블로 분리해 따로 관리하는 작업을 마치면 제2정규화가 완료된다.
- 위에서 말했지만, 부분적 함수 종속이 더이상 발생하지 않는다면 이를 완전 함수적 종속이라 칭한다.
- 하지만 단점으로는 특정 유저가 프로그램을 배우는데 내야하는 비용 전체를 파악하려면 테이블 하나만 확인해서는 알 수가 없다.
Program | Instructor | Degree |
---|
Weight trainning | Will | Ph.D |
Body weight trainning | Will | Ph.D |
Boxing | James | Bachelor's |
Yoga | Kim | Master's |
Pilates | Mark | Ph.D |
- 제2 정규화를 마친 위와 같은 테이블이 있다.
- composite primary key가 없기 때문에 partial dependency가 존재하지 않으므로 제2정규형 테이블.
- 제3 정규화란, 제2 정규화를 만족하는 테이블에 대해 이행적 종속이 없도록 테이블을 분해하는 행위를 의미한다. (There is no transitive dependency)
- 이행적 종속: A->B, B->C란 관계가 있을때, A->C가 성립될 때 이행적 종속이라 칭한다.
- 이 경우가 위의 테이블에선
Program
-> Instructor
, Instructor
-> Degree
의 관계가 해당된다. 따라서, Degree
컬럼을 분리해 새로운 테이블에서 관리할 수 있다.
- 즉,
Program
을 통해 Instructor
을 참조하고, Instructor
을 통해 Degree
를 참조하는것을 말한다.
- 이 과정을 거치면 아래와 같이 테이블을 분리할 수 있다.
Program | Instructor |
---|
Weight trainning | Will |
Body weight trainning | Will |
Boxing | James |
Yoga | Kim |
Pilates | Mark |
Instructor | Degree |
---|
Will | Ph.D |
James | Bachelor's |
Kim | Master's |
Mark | Ph.D |
- 필요성? => 제3 정규화를 하지 않으면,
Program
의 Instructor
가 바뀌었을때, 해당 교사의 Degree
도 따로 수정해 줘야 한다. 하지만 제3 정규화를 해놓으면 Instructor
만 바꾸면 Degree
는 Instructor
를 참조하기 때문에 자동으로 따라간다.
1NF ~ 3NF 요약
- 1NF: PK, 원자성
- 2NF: 부분 함수적 종속 X -> 완전 함수적 종속
- 3NF: 이행 함수적 종속 X