기록공간

정규화(Normalization) 본문

DataBase

정규화(Normalization)

입코딩 2020. 10. 11. 15:35
반응형

데이터베이스의 경우 그 구조가 잘못된 경우, 프로젝트를 다시 만들어야 할 정도로 설계가 끝나고 프로그램을 개발하는 도중에는 설계 구조의 변경이 불가능하다. 그렇기 때문에 프로젝트에서의 데이터베이스 오류를 줄이고 자원을 효율적으로 관리하기 위해서는 반드시 정규화 과정을 거쳐야 한다. 그러면 정규화란 도대체 무엇일까?

 

정규화란 한 마디로 데이터베이스 서버의 메모리 낭비를 막기 위해 어떤 하나의 테이블을 식별자를 가지는 여러 개의 테이블로 나누는 과정을 말한다.

 

정규화에는 4단계의 과정이 존재한다. 그러면 예를 들면서 어떤 과정이 있고 어떻게 정규화가 진행되는지 살펴보도록 하겠다.

 

제 1 정규화 

예를 들어 철수가 옥장판을 판매하는데 고객 리스트를 데이터베이스화 하려고 한다 가정하자. 테이블의 데이터는 다음과 같다.

 

서울 여의도 LG라는 회사에 근무하는 거래처 직원 명단이 총 100만 명이라고 가정한다.(70Byte*1000,000) 

전체 직원은 200만 명이다.

 

그런데 어느 날 서울 여의도에 위치한 LG 본사가 경기 일산으로 사옥을 이전하게 되었다. 회사 주소는 경기 일산으로 바뀌고, 회사 전화는 031-111-2222로 바뀌게 되었다. 그러면 UPDATE 쿼리문을 사용하여 100만 명의 회사주소와 회사 전화를 변경해야 한다. 다음처럼 말이다.

 

UPDATE 거래처직원
SET 회사주소 = '경기일산', 회사전화 = '031-111-2222'
WHERE 거래처회사명 = 'LG'
    AND 회사주소 = '서울여의도';

이런 경우 서울 여의도 LG에 근무하는 100만 개의 직원 레코드를 하드디스크 상에서 읽어다가 메모리에 로드시켜 줘야 한다. 즉, 100만 * 70Byte를 모두 하드디스크 상에서 읽어다가 메모리에 로드시켜 주어야 한다는 말이다. 

 

이는 테이블의 설계가 잘못되었으므로 데이터베이스 서버는 조만간 메모리 고갈로 인해 DOWN 될 것이다. 그렇게 때문에 정규화 과정을 수행해야 한다. 

 

우선 이런 메모리(중복되는 값)를 어떻게 줄여야 할지에 대한 방법을 생각해 봐야 할 것이다. 

 

여기서 우리는 중복되는 데이터 값들만 모아 테이블을 따로 만들어 주면 되지 않을까? 라는 생각이 들것이다. 바로 이것이 제 1 정규화 과정이다.    

 

제 1 정규화는 어떤 하나의 테이블에서 반복(중복)되는 컬럼 값들이 존재한다면 값들이 반복되어 나오는 컬럼을 분리하여 새로운 테이블을 만들어주는 과정을 일컫는다. 

 

중복되는 데이터는 회사 정보이므로 회사 테이블과 직원 테이블로 나눠볼 수 있을 것이다.

 

제 1 정규화를 수행하는 과정에서 분리된 테이블은 반드시 부모 테이블과 자식 테이블의 관계를 갖게 된다. 여기서는 회사 테이블이 부모, 직원 테이블이 자식이 된다. 

 

부모 테이블에는 테이블의 값이 유일한 값임을 보장하는 기본키(PRIMARY KEY)가 반드시 필요하다. 그리고 자식 테이블에는 부모 테이블의 정보를 참조하는 외래키(FOREIGN KEY)가 반드시 필요하다. 즉 부모 테이블의 기본키는 항상 자식 테이블의 외래키로 전이된다

 

이전 상태로 테이블을 조회하고 싶은 경우 두 테이블을 서로 JOIN 해주면 된다.

 

SELECT A.거래처회사명, A.회사주소, A.회사전화,
    AND B.거래처직원명, B.직급, B.이메일, B.휴대폰
FROM 회사 A, 직원 B
WHERE A.회사ID = B.회사ID;

이제 제 1 정규화를 한 상태에서 앞에서 하려 했던 작업 다시 진행해 보도록 하겠다. UPDATE 쿼리문을 사용한다.

 

UDPATE 회사
SET 회사주소 = '경기일산', 회사전화 = '031-111-2222'
WHERE 회사ID = 10;

모든 직원의 회사 정보를 바꿀 필요가 사라졌다. 또한 1개의 행만 하드디스크 상에서 읽어다가 메모리에 로드시켜 줬다. 총 40Byte만 메모리에 로드시켜 줬기 때문에 메모리를 아주 많이 아낄 수 있다. 정규화 이전에는 100만 건을 처리해야 할 업무에서 1건만 처리하는 되는 업무로 바뀐 상황이기 때문에 데이터베이스 서버는 메모리 고갈이 일어나지 않고 아주 빠르게 처리될 것이다. 엄청난 발전이다!

 

-- 거래처회사명, 거래처직원명
--> 제 1 정규화 이전
SELECT 거래처회사명, 거래처직원명
FROM 거래처직원;

--==>> 200만 * 70Byte 

--> 제 1 정규화 이후
SELECT A.거래처회사명, B.거래처직원명
FROM 회사 A JOIN 직원 B
ON A.회사ID = B.회사ID;

--==>> (3 * 40Byte) + (200만 * 50Byte)

또한 전체 데이터를 조회하는 데에서도 정규화 이전과 이후에서 차지하는 메모리가 많이 줄었다.

 

제 2 정규화

다음과 같이 제 1 정규화 과정을 거친 두 테이블이 있다고 가정하자.

 

위 거래처 테이블과 다른 점이 있다면 기본키, 외래키의 컬럼이 한 개가 아닌 두 개이다.

 

제 2 정규화는 기본키, 외래키 컬럼이 한 개라면 (Single column) 수행하지 않는다. 하지만 컬럼이 두 개 이상인 경우 (Composite column) 반드시 제 2 정규화를 수행해야 한다

 

식별자가 아닌 컬럼은 식별자 전체 컬럼에 대해 의존적이어야 하는데 식별자 전체 컬럼이 아닌 일부 식별자 컬럼에 대해서만 의존적이라면 이를 분리하여 새로운 테이블을 생성해 줘야 한다. 이 과정을 제 2 정규화라고 한다. 

 

교수번호는 중복된 값이 있기 때문에 단독으로 존재할 수 없는 기본키이지만 서로 같이 붙여놓고 보면 단독으로 존재할 수 있는 Composite column 기본키가 된다. 그러므로 여기서는 과목 테이블의 과목번호와 교수번호 기본키를 따로 나눠줘야 할것이다. 또한 점수 테이블 또한 과목번호와 학번 둘 다 컬럼의 경우 단독으로 존재할 수 없지만 서로 붙이면 기본키가 될 수 있기 때문에 과목번호, 학번을 따로 나눠줘야 한다.

 

제 3 정규화

제 3 정규화는 식별자가 아닌 컬럼이 식별자가 아닌 컬럼에 대해 의존적인 상황이라면, 이를 분리하여 새로운 테이블을 생성해 주는 과정이다. 위 과목 테이블에서 강의실 코드와 강의실 설명은 기본키가 아님에도 불구하고 서로 의존적인 관계이다. 때문에 이 둘을 서로 다른 테이블에 분리해 줘야 한다.

 

제 4 정규화

다음과 같은 테이블들이 있다고 가정하자.

 

제 4 정규화에 대해 알아보기 전에 테이블 관계(Relation)의 종류를 먼저 알아봐야 한다. 

 

  • 1 : Many(다) 관계 : 제 1 정규화를 적용하여 수행을 마친 결과물에서 나타나는 바람직한 관계이다. 관계형 데이터베이스를 활용하는 과정에서 반드시 추구해야 하는 관계이다.

  • 1 : 1 관계 : 논리적, 물리적으로 존재할 수 있는 관계이지만 관계형 데이터베이스 설계 과정에서는 가급적이면 피해야 할 관계이다. 

  • Many(다) : Many(다) 관계 : 논리적인 모델링에서는 존재할 수 있지만 실제 물리적인 모델링에서는 존재할 수 없는 관계 

 

 

제 4 정규화는 이런 Many(다) : Many(다) 관계를 1 : Many(다) 관계로 깨뜨리는 과정이다. 파생 테이블을 생성하여 이런 관계를 깨뜨린다. 

 

역정규화(비정규화)

역정규화는 말 그대로 정규화를 거친 과정을 되돌리는 것을 말한다. 나눴던 테이블(혹은 컬럼을)을 서로 합치는 것을 예로 들 수 있다.

 

다음과 같은 테이블이 있다고 가정하자. 여기서 부서명, 사원명, 직급, 급여의 데이터를 검색하고 싶다고 하자.

 

부서 테이블과 사원 테이블을 JOIN 했을 때의 크기를 구해보면 다음과 같다.

 

(500,000 * 30Byte) + (1,000,000 * 60Byte) = 15,000,000 + 60,000,000 = 75,000,000Byte

하지만 역정규화를 한다면(부서명 컬럼을 사원 테이블에 합침) JOIN할 필요없이 결과는 다음과 같을 것이다. 

 

 10,000,000 * 70Byte = 70,000,000Byte

역정규화를 통해 차지하는 메모리가 조금 줄었다.

 

하지만 다음과 같이 부서와 사원 테이블의 데이터 개수의 차이가 많이 나는 경우에는 역정규화를 하면 안 된다. 

 

--역정규화를 하지 않고 JOIN 했을 떄의 크기
(10 * 30Byte) + (1,000,000 * 60byte) = 300 + 60,000,000 = 60,000,300Byte

--역정규화를 거친 후 크기
10,000,000 * 70Byte = 70,000,000Byte

 

반응형

'DataBase' 카테고리의 다른 글

무결성(Integrity) 제약조건  (0) 2020.10.18
데이터베이스(Database)  (0) 2020.10.03
Comments