데이터베이스 정규화에 대해 추상적인 개념만 있어서 정리하며 머리속에 넣기위한 글입니다.
정규화란?
정규화의 기본적인 목표는 테이블 간에 중복된 데이터를 허용하지 않는다는 것이다.
중복된 데이터를 허용하지 않아 데이터의 무결성을 유지, DB의 저장 용량을 줄 일 수 있다.
테이블을 분해하는 정규화 단계가 있다.
- 제1 정규화
- 제2 정규화
- 제3 정규화
테이블을 어떻게 분해하는지는 정규화 단계에 따라 달라진다.
제1 정규화
제1 정규화란 테이블의 컬럼이 원자값을 가지도록 테이블을 분해하는 것이다.
개발자의 이름과 기술스택 컬럼을 가지는 개발자 정보 테이블을 보자.
이름 | 기술 스택 |
찰리 | Java,Spring |
브라운 | Node.js |
스누피 | Kotlin, Spring |
찰리와 스누피는 여러개의 기술 스택을 가지고 있다. 이때 하나의 레코드의 데이터가 여러개의 값을 표현하고 있으므로 제1 정규화를 만족하지 못하는 것이다.
제1 정규화를 진행하면 아래와 같은 모습이 된다.
이름 | 기술 스택 |
찰리 | Java |
찰리 | Spring |
브라운 | Node.js |
스누피 | Kotlin |
스누피 | Spring |
제2 정규화
제2 정규화는 제1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것이다.
함수 종속이란?
관계 스키마 중에서 어느 속성군의 값이 정해지면 다른 속성군의 값이 정해지는 것.
A, B가 각각 관계 R의 속성인 경우, 임의 시점에서 A의 어떤 값도 반드시 B의 하나의 값에 대응되지만,
B의 하나의 값이 A의 복수의 값에 대응되는 경우에 B는 A에 함수 종속이라고 한다. (A -> B와 같이 표기.)
ex. 직원 테이블이 "직원 ID", "직원 생일" 속성을 가질 때, [직원 ID] -> [직원 생일]이다. 즉, 직원 생일은 직원 ID에 함수 종속이다.
완전 함수 종속이란?
A,B가 각각 관계 R의 속성이고 B가 A에 함수 종속(A->B)인 경우,
A의 임의의 부분 집합에 대하여 B의 어떤 값도 A의 부분 집합의 값에 대응하지 않으면 B는 A에 완전 함수 종속이라고 한다.
여기서 완전 함수 종속이라는 것은 기본키의 부분집합이 결정자가 되어서는 안된다는 것을 의미한다.
아래의 수강 강좌 테이블을 보자.
학생번호 | 강좌이름 | 강의실 | 성적 |
10 | 데이터베이스 | 공학관 110 | 3.5 |
10 | 자료구조 | 공학관 111 | 3.5 |
20 | 스포츠경영학 | 체육관 103 | 4.0 |
30 | 데이터베이스 | 공학관 110 | 4.0 |
30 | 자료구조 | 공학관 111 | 3.5 |
이 테이블의 기본키는 (학생번호, 강좌이름)으로 복합키를 가진다.
(학생번호, 강좌이름)은 성적을 결정한다. (학생번호, 강좌이름) -> 성적
여기서 강의실이라는 컬럼은 기본키의 부분집합인 (강좌이름)에 의해 결정될 수 있다.
따라서 (학생번호, 강좌이름) 복합키의 부분집합인 '강좌이름 -> 강의실' 이므로 제2 정규화를 만족할 수 없다.
강의실을 별도로 분리하여 관리하면 제2 정규형을 만족할 수 있다.
학생번호 | 강좌이름 | 성적 |
10 | 데이터베이스 | 3.5 |
10 | 자료구조 | 3.5 |
20 | 스포츠경영학 | 4.0 |
30 | 데이터베이스 | 4.0 |
30 | 자료구조 | 3.5 |
강좌이름 | 강의실 |
데이터베이스 | 공학관 110 |
자료구조 | 공학관 111 |
스포츠경영학 | 체육관 103 |
데이터베이스 | 공학관 110 |
자료구조 | 공학관 111 |
제3 정규화
제3 정규화란 제2 정규화를 진행한 테이블에 대해 이행함수 종속을 없애도록 테이블을 분해하는 것이다.
이행함수 종속이란?
A -> B 이고 B -> C가 성립할 때 A -> C가 성립하면 이행함수 종속이라고 한다.
다음의 강좌 테이블을 보자
학생번호 | 강좌이름 | 수강료 |
10 | 데이터베이스 | 20000 |
10 | 자료구조 | 30000 |
20 | 스포츠경영학 | 15000 |
30 | 데이터베이스 | 20000 |
30 | 자료구조 | 30000 |
학생 번호는 강좌 이름을 결정하고 있고, 강좌 이름은 수강료를 결정하고 있다. 또한 학생번호가 수강료를 결정하고 있으므로 이행함수 종속이 성립됐다. 때문에 제3 정규화를 만족하려면 테이블을 분리해야한다.
이행함수 종속을 제거하지 않으면 어떤일이 벌어질까?
강좌의 수강료가 변경됐다고 해보자. 데이터베이스 강좌의 수강료가 20000원 -> 40000원으로 인상됐다.
이 때 수정해야할 레코드가 여러개가 발생한다.(학생번호 10, 30의 레코드를 수정해야함) 이를 제3 정규화를 통해 극복할 수 있다.
학생번호 | 강좌이름 |
10 | 데이터베이스 |
10 | 자료구조 |
20 | 스포츠경영학 |
30 | 데이터베이스 |
30 | 자료구조 |
강좌이름 | 수강료 |
데이터베이스 | 20000 |
자료구조 | 30000 |
스포츠경영학 | 15000 |
이제 데이터 중복이 많이 줄어들었다.
수강료 변경이 생기면 아래의 테이블만 변경하면 된다.
참고자료
'DB' 카테고리의 다른 글
[DB] JOIN ON 과 WHERE 의 차이 (1) | 2023.03.27 |
---|---|
JOIN 정리 (INNER JOIN, LEFT JOIN, RIGHT JOIN) (0) | 2023.03.27 |
[MySQL] Replication 적용기 - 1 (4) | 2021.10.22 |
[MariaDB] Docker Container에 올렸던 DB서버 로컬로 빼내기 (0) | 2021.09.11 |
댓글