이번 지하철 미션을 하면서 테이블 설계 과정이 중요성을 배울 수 있었다. 페어프로그래밍 중 테이블을 설계하는 과정에서 정규화
라는 단어가 많이 나왔지만 이에 대한 개념이 부족하다는 것을 깨달았고 정리해보는 시간을 가져보려고 합니다.
위키피디아에 따르면 데이터베이스의 정규화
는 관계형 데이터베이스의 설계에서 중복을 최소화하게 데이터를 구조화하는 프로세스라고 합니다. 이 말 뜻을 그대로 받아들이면 중복되는 데이터를 허용하지 않음으로써 데이터의 무결성을 유지하기 위함으로 이해하면 좋을 것 같습니다.
💡 데이터 무결성이란?
데이터 무결성은 데이터의 정확성, 일관성 등이 유지되는 것을 의미합니다.
데이터의 정확성 : 데이터의 중복이나 누락이 없는 상태
데이터의 일관성 : 원인과 결과의 의미가 연속적으로 보장되어 변하지 않는 상태
정규화의 종류로는 제1정규형, 제2정규형, 제3정규형 BCNF 정규화 등이 있습니다. 각 정규화는 정규화 단계를 의미하며 테이블을 분리하는 방법으로 보면 됩니다.
먼저 1정규화에 대해서 알아보겠습니다.
제1 정규화
란 테이블의 열의 값이 원자성
을 갖도록 테이블을 분리하는 것을 의미합니다. 여기서 원자성은 하나의 값을 가지는 것을 의미합니다. 예를 들면 다음과 같은 역과 호선의 테이블이 존재한다고 하겠습니다.
지하철 역 | 호선 |
---|---|
잠실역 | 2호선, 8호선 |
남위례역 | 8호선 |
강남역 | 2호선 |
복정역 | 8호선, 분당선 |
위의 테이블을 보면 남워례역과 강남역의 경우 호선 정보의 원자성이 지켜졌지만 잠실역과 복정역의 경우 호선 정보의 원자성이 지켜지지 않은 것을 볼 수 있습니다. 이 테이블에 제1 정규화를 하면 다음과 같이 됩니다.
지하철 역 | 호선 |
---|---|
잠실역 | 2호선 |
잠실역 | 8호선 |
남위례역 | 8호선 |
강남역 | 2호선 |
복정역 | 8호선 |
복정역 | 분당선 |
다음으로 제2 정규화에 대해서 알아보겠습니다.
제2 정규화
란 제1 정규화를 진행한 테이블에 대해 완전 함수 종속
을 만족하도록 테이블을 분리하는 것을 의미힙니다.
💡 완전 함수 종속이란?
기본키로 종속자가 결정되어야하는 것으로 기본키의 부분집합이 결정자기 되어서는 안된다는 것을 의미합니다.
열차 예매 테이블을 예시로 설명하겠습니다.
고객번호 | 열차이름 | 대기실 | 금액 |
---|---|---|---|
001 | 무궁화호 | A15 | 10,000 |
002 | ktx | B13 | 30,000 |
004 | 새마을호 | C12 | 15,000 |
011 | srt | D15 | 20,000 |
열차 예매 테이블은 기본키로 (고객번호, 열차이름)인 복합키입니다. 여기서 (금액)의 경우 기본키인 (고객번호, 열차이름)으로 결정됩니다. 하지만 (대기실)의 경우 기본키의 부분집합인 (열차이름)만으로도 결정이 됩니다. 이 부분이 완전 함수 종속을 위반하는 것으로 볼 수 있습니다.
제2 정규화를 적용하면 다음과 같이 테이블을 관리할 수 있습니다.
예매 테이블
고객번호 | 열차 | 금액 |
---|---|---|
001 | 무궁화호 | 10,000 |
002 | ktx | 30,000 |
004 | 새마을호 | 15,000 |
011 | srt | 20,000 |
열차 테이블
열차 | 대기실 |
---|---|
무궁화호 | A15 |
ktx | B13 |
새마을호 | C12 |
srt | D15 |
위의 같이 테이블은 관리하면 완전 함수 종속을 만족할 수 있습니다.
다음으로는 제3 졍규화에 대해서 알아보겠습니다.
제3 정규화
란 제2 정규화를 한 테이블에서 이행적 종속
을 제거하는 테이블 분리 방법을 의미합니다.
💡 이행적 종속이란?
이행적 종속이란 테이블에서 a,b,c 라는 속성이 존재할 때 a → b, b→ c와 같은 종속 관계가 있을 경우 a → c가 성립하는 경우 이행적 함수 종속이라고 합니다.
앞선 제2 정규화가 된 테이블 중 예매 테이블을 예시로 보겠습니다.
예매 테이블
고객번호 | 열차 | 금액 |
---|---|---|
001 | 무궁화호 | 10,000 |
002 | ktx | 30,000 |
004 | 새마을호 | 15,000 |
011 | srt | 20,000 |
예매 테이블을 보게되면 고객번호는 열차를 결정합니다. 그리고 열차는 금액을 결정하는 것을 알 수 있습니다. 즉, 고객번호 → 열차과 열차 → 금액의 종속관계가 결정되는데 고객번호 → 금액의 관계가 성립하는 것을 볼 수 있습니다. 이와 같이 현재 테이블은 이행적 종속을 가진다고 볼 수 있습니다. 이행적 종속이 제거되어야 하는 이유는 데이터를 수정하는 범위를 줄이기 위함입니다. 예를 들면 001의 고객이 srt로 열차로 변경하면 금액 역시 수정이 필요합니다. 이를 제3 정규화를 통해 이 테이블을 다음과 같이 분리할 수 있습니다.
예매 테이블
고객번호 | 열차 |
---|---|
001 | 무궁화호 |
002 | ktx |
004 | 새마을호 |
011 | srt |
예매 금액 테이블
열차 | 금액 |
---|---|
무궁화호 | 10,000 |
ktx | 30,000 |
새마을호 | 15,000 |
srt | 20,000 |
위와 같이 테이블을 관리하면 테이블 내 이행적 종속을 제거한 것을 확인할 수 있습니다.
정규화를 명확하게 이용하면 테이블 내에서 발생할 수 있는 데이터의 중복을 줄일 수 있다는 것을 직접 테이블을 분리해보면서 알 수 있었다. 하지만 테이블이 많아지게 되면 관리하는 비용이 높아지게 되고 데이터를 조회하는 과정에서 빈번한 join이 발생하게 될 텐데 오히려 성능 부분에서는 데이터를 중복을 허용하는 것이 좋지 않을까? 하는 생각이 들었다. 이 부분에 대해서는 직접 경험해보며 정규화를 하는 것에 대한 기준을 세우는 것이 좋을 것 같다.