DB 정규화에 관하여

정규화

정규화란 잉여 데이터의 최소화 하도록 정리하는 것.
(organizing the data into multiple related tables to minimize data redundancy)

1. data redundancy란?


의미없는 데이터들이 테이블에서 여러번 중복해서 많은 row에 있는 경우를 의미한다.

예를 들어 student 라는 테이블에 departmentdepartment_phone_number라는 칼럼이 있다면 student의 row가 추가될 때마다 두 칼럼엔 아마 같은 데이터들이 계속해서 쌓일 것이다.

이는 DB의 용량을 차지하는 문제를 야기할 뿐더러 다른 문제들도 야기한다.

아래 3가지의 문제를 수반한다.

1) insertion anomaly

- student를 추가할 때 마다 (별 필요도 없는) department 정보도 저장이 된다.

2) deletion anomaly

- student를 지우면 department 정보도 날아가게 된다.
- 만약 모든 student를 지우면? 모든 department도 날아가게 되는 것이다!

3) update anomaly

- 만약 department가 새로운 이름으로 개명했다면? 모든 row의 department를 바꿔줘야 한다.

하지만 정규화란, eliminating data redundancy가 아니다. minimizing redundancy다.

만약 department_phone_number 칼럼은 존재하지 않고 department만 존재한다면?

여전히 department 정보가 필요없다고 날려버릴 것인가? 안 된 다

이 때는 department 칼럼을 제거할 수 없다. 왜냐면 이 때 department는 외래키 역할을 하며 다른 정보를 불러오는데 필수인 다리 역할도 할 것이기 때문이다.

보시다시피, 이 때는 department라는 칼럼은 redundant하지만 그렇다고 eliminate할 수 없다. 우린 그저 data redundancy를 minimize한 것이고 이게 바로 DB 정규화다.

정규화에도 여러가지 단계가 있다.

2. 1차 정규화


""" 이것조차 안하면 DB를 쓰지말라고 하지만 보통은 DBMS에서 1차 정규화는 할 수 있도록 잡아주기 때문에 이런 경우가 있을까 싶다. """

1) 한 셀엔 하나의 데이터만 존재해야 한다.
2) 각 칼럼의 데이터 타입은 모두 동일해야 한다.
3) 각 칼럼명은 고유해야 한다.
4) 데이터가 DB에 저장되는 순서는 중요하지 않다.

3. 2차 정규화


2차 정규화의 조건

- 1차 정규화를 거쳐야한다
- partial dependancy가 없어야 한다

먼저 디펜던시란 무엇인가?

auto_increment되는 primary key가 있는 student table이 있다고 가정하자.
auto_increment되는 pk를 참조하면 우리는 어떤 행이든 다 데이터를 가져올 수 있다.
우리는 다양한 다른 데이터를 retrieve하기 위해선 auto_increment PK에 의존해야 한다.
여타 데이터를 얻기 위해 필요한 값, 이 게 디펜던시다.

그렇다면 partial dependancy를 제거하려면 어떻게 해야 하는가?

테이블 내 컬럼들 중 일부 키에만 종속된 컬럼이 없어야 한다.

예를 들어 subject student score age 라는 4개의 칼럼을 가진 테이블이 있다 치자.
이 중 score는 학생과 과목 정보가 반드시 있어야 하는 데이터다.
학생만 알아서도 안되고(무슨 과목의 점수인지 모르기 때문) subject만 알아서도 안 된다. (누구의 점수인지 모르기 때문)

그래서 score는 student, subject 두 키에 모두 의존한다.

하지만 age는?
subject를 모른다고 해서 student의 나이도 모르는 것은 아니다.
student 값만 알면 age는 구할 수 있다. 이 경우에 age는 student key에만 의존하는 것이고
이게 바로 partial dependancy (부분 디펜던시)이다.

2차 정규화에서는 이 부분을 없애야 한다.

4. 3차 정규화

3차 정규화의 조건은

- 2차 정규화를 만족해야 한다.
- Transitive Depedancy가 없어야 한다.

Transitive Depedency란? 이행적 종속이라고 하는데
쉽게 말해 PK 외에 다른 Key가 다른 칼럼을 결정할 수 없다는 것이다.

기본키가 아닌 열끼리의 종속 관계가 있으면 안된다.
그럴 경우엔 종속관계가 있는 것들을 분리해서 따로 테이블을 만들어주어야 한다.

예를 들어 student 테이블에

student_id, student_name, mark, grade 라는 칼럼이 있다치자
mark가 50 이상이면 grade가 A / 50미만이면 grade가 B다.

이 때 grade는 mark에 종속된다. 하지만 mark는 student 테이블의 PK가 아니다.
그리고 grade는 mark에 의존한다.
이 때는 mark table을 새로 파서 grade가 mark를 pk로, grade를 mark에 종속된 칼럼으로 만들어두면 된다.

그럼 student table은 student_id, student_name, mark_id 칼럼을 갖게 되고
mark table은 mark_id, mark, grade 칼럼을 갖게 된다.



5. BCNF 정규화


bcnf(boyce-codd)normal form 정규화

조건
- 3차 정규화를 만족해야 한다.
- 어떠한 dependancy라도 pk는 슈퍼키여야 한다.

용어설명

결정자 : 다른 칼럼의 값을 결정짓게 하는 칼럼(데이터)
후보키 : 기본키로 사용할 수 있는 (PK가 될 수 있는) 키들. 유일성과 최소성을 만족해야한다.
슈퍼키 : 하나 이상의 속성들의 집합으로 이루어진 것 (합체해서 하나의 행만 잘 찾아낸다면 ㅇㅋ)

슈퍼키는 유일성은 만족하지만 (합쳐진 속성들을 바탕으로 유일한 행을 찾을 수 있기 때문에)
최소성은 만족하지 않는다.

* 최소성이란, 레코드를 식별하는데 꼭 필요한 속성들로만 구성해야 한다는 것.

근데 슈퍼키는 두 개 이상이 합쳐서 유일성을 갖게 되니까 이미 최소성을 갖지 못하는 것
슈퍼키가 되려면 슈퍼키 내에는 반드시 하나 이상의 후보키가 있어야 한다.
따라서 슈퍼키 = (후보키 + 다른키) 이니까 최소성을 만족하지 못하는 것.

bcnf?

다른 dependancy를 유발하는 키가 A라면(A가 결정자라면), A는 반드시 후보키이어야 한다.

(교수가 1과목만 가르칠 수 있고, 한 과목은 여러명의 교수가 있을 수 있다고 가정할 때)
학생번호 / 과목 / 교수 테이블이 있다고 하자

이 때 교수는 non prime인데(후보키가 아닌데) prime key인 <과목> 칼럼을 결정짓는다.
이러면 BCNF 조건을 만족하지 못하는 것이다.



댓글

이 블로그의 인기 게시물

로컬 Tomcat 서버 실행속도 개선

2019.05.23 - SQLAlchemy 의 객체 상태 관리 (expire, refresh, flush, commit) 에 관한 이해

2020.02.17 Python의 multiprocessing 중 Pool.map(), chunksize에 관한 내용