[DB] 데이터 베이스 정규화 (Normalization) 란?

반응형

 

 

관계형 데이터베이스를 배우거나 SQLD (SQL 개발자), 정보처리기사 등 시험에 자주 출제되지만, 처음 배우면 함수종속성, 중복속성, 부분종속, 이행종속 등등.. 한자어로 1~2줄 설명으로 끝나기 십상이라 이해하기 힘들었던 경험 모두 있을 것이다. 쉽게 이해해보자.

 

1. 데이터베이스 정규화 (Normalization)

관계형 데이터베이스 설계에서 중복을 최소화하도록 데이터를 구조화하는 것을 정규화(Normalization) 라고 한다.

 

 

2. 제1정규화, 제1정규형(1NF)

※ NF는 Nomal Format의 약자이다

 

우리는 파스타 면의 판매업체로 다음과 같은 상품판매채널 테이블이 존재한다고 가정하자.

상품모델(id) 상품명(item_name) 판매채널(channel)
s001 스파게티 자사몰
p001 페투치네 오픈마켓
l001 링귀니 자사몰

 

자사몰에서만 판매하고있던 링귀니를 대형마트에 납품하게 되었다고 가정해보자. 그렇다면 어떻게 추가해야할까?

 

이렇게 기존 링귀니 판매채널 컬럼에 '대형마트'를 추가하는 방법이 있다.

상품모델(id) 상품명(item_name) 판매채널(channel)
s001 스파게티 자사몰
p001 페투치네 오픈마켓
l001 링귀니 자사몰, 대형마트

 

그런데 이렇게하면 나중에 문제가 될 수 있다.

만약 자사몰에서만 판매하는 상품만 찾고싶다면? 조건문에 신경을 써야한다.

-- 아래와 같이 검색하면 판매채널에 '자사몰'만 등록되어있는 데이터만 찾아진다.
SELECT * FROM item WHERE channel = '자사몰';

-- 따라서 다음과 같이 조건식을 사용해야 할 것이다.
SELECT * FROM item WHERE channel LIKE '%자사몰%';

 

그리고 또, 갑자기 판매채널 명칭을 바꾼다고 한다면? '대형마트'에서 세분화하여 '이마트'로 변경한다면? 데이터 수정이 쉽지 않다.

 

그래서, 보통은 다음과 같은 방법으로 데이터를 추가한다.

상품모델(id) 상품명(item_name) 판매채널(channel)
s001 스파게티 자사몰
p001 페투치네 오픈마켓
l001 링귀니 자사몰
l001 링귀니 대형마트

 

이렇게 하나의 컬럼에는 하나의 데이터만 포함하는 것제1정규화 라고 한다.

그리고 이러한 제1정규화 된 테이블을 제1정규형(1NF)을 만족하는 테이블 이라고 한다.

 

 

3. 제2정규화, 제2정규형(2NF)

다음과 같이 상품판매채널 테이블에 데이터가 있다고 가정하자.

상품모델(id) 상품명(item_name) 가격(price) 판매채널(channel)
s001 스파게티 3000 자사몰
p001 페투치네 3500 오픈마켓
l001 링귀니 5000 오픈마켓
l001 링귀니 5000 자사몰
l001 링귀니 5000 대형마트

 

만약에 링귀니 제품의 가격 상승이 발생하면 어떻게될까? 지금은 고작 5개의 데이터 뿐이지만..

실제로 수많은 데이터들은 존재할텐데, 그 많은 데이터의 가격을 일괄 수정해야한다.

그러면 시간과 비용이 많이 발생하게 되버린다.

 

이러한 비효율을 방지하기위해 하는 것이 제2정규화라 생각하면 된다.

현재 테이블과 관련없는 데이터를 테이블로 따로 빼서 관리하는 것을 의미한다.

 

잘 생각해보자. 현재 테이블에서 가격(price) 컬럼은 반드시 존재해야 하는 컬럼일까?

다음과 같이 상품가격 테이블을 따로 만들어서 가격만 따로 관리하면 되지 않을까?

 

  • 상품판매채널 테이블
상품모델(id) 상품명(item_name) 판매채널(channel)
s001 스파게티 자사몰
p001 페투치네 오픈마켓
l001 링귀니 오픈마켓
l001 링귀니 자사몰
l001 링귀니 대형마트

 

  • 상품가격 테이블
상품모델(id) 상품명(item_name) 가격(price)
s001 스파게티 3000
p001 페투치네 3500
l001 링귀니 5000

 

이를 명확히 정의하면 테이블 내에서 부분 함수 종속(Partial Functional Dependency)을 제거하여 완전 종속인 테이블을 만드는 것이 제2정규화 라고 하며, 제2정규화 된 테이블제2정규형(2NF) 테이블이라 한다.

 

이렇게 제2정규화를 하면, 상품가격 데이터 수정을 할 때 전체를 수정하지않고 한곳만 수정하면 되므로 성능상 우수해진다.

하지만, 상품판매채널 테이블만으로 상품가격을 알 수 없게 되므로, 상품가격을 알기 위해서는 JOIN 등의 작업이 필요해진다.

 

■ 부분 함수 종속(Partial Functional Dependency)에 대해서

다음과 같이 상품판매채널 테이블을 보자. 가격은 '판매채널'과 관계까 있을까? '판매채널'과 관계가 있다면, 판매채널마다 가격이 정해질 것이다. 하지만 여기서 가격은 상품이 무엇이냐에 따라 정해지는 것이기 때문에 가격(price) 은 상품모델(id)과 상품명(item_name) 에 종속된다. 이럴때 상품모델(id)과 상품명(item_name)이 결합하여 하나의 Key가 되고 가격은 종속되고 있다. 이런 것을 두고 테이블에 부분종속적인 컬럼이 있다고 표현한다.

※ 두 개 이상의 컬럼을 key 로 지정하는 것을 복합 키 (Composite Key) 라고한다.

상품모델(id) 상품명(item_name) 가격(price) 판매채널(channel)
s001 스파게티 3000 자사몰
p001 페투치네 3500 오픈마켓
l001 링귀니 5000 오픈마켓
l001 링귀니 5000 자사몰
l001 링귀니 5000 대형마트

 

 

4. 제3정규화, 제3정규형(3NF)

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

  • 상품가격 테이블
  • PK : 상품모델(id), 상품명(item_name)
상품모델(id) 상품명(item_name) 가격(price) 공급자(vendor) 공급국가(factory_country)
s001 스파게티 3000 DECE italy
p001 페투치네 3500 RUMM italy
l001 링귀니 5000 VALL america

 

공급자의 국가(factory_country)는 공급자(vendor)에 종속적이다. 

 

여기서 공급자(vendor)는 일반 컬럼이고 키역할을 하지 않는다.

공급자의 국가(factory_country)는 PK와 아무 연관이 없다.

 

일반 컬럼에만 종속되는 데이터를 분리하는 것제3정규화 라고 한다.

제3정규화 된 테이블제3정규형(3NF) 테이블 이라 한다.

 

  • 상품가격 테이블
  • PK : 상품모델(id), 상품명(item_name)
상품모델(id) 상품명(item_name) 가격(price) 공급자(vendor)
s001 스파게티 3000 DECE
p001 페투치네 3500 RUMM
l001 링귀니 5000 VALL
  • 공급자 테이블
  • PK : 공급자(vendor)
공급자(vendor) 공급국가(factory_country)
DECE italy
RUMM italy
VALL america

 

이렇게 나눠두면 수정등의 작업에 용이해진다.

하지만 상품명으로 공급국가를 알기 위해서는 테이블 하나만으로 알 수 없고 JOIN 의 작업이 요구된다.

 

5. 반정규화(De-normalization)

정규화된 데이터를 시스템의 성능향상, 단순화 등을 목적으로 중복, 통합, 분리 등을 수행하는 기법이다.

 

정규화로 인하여 테이블이 분리되었을때, 과도한 JOIN 이 발생하여 조회성능저하가 예상되는 경우 수행하므로 다음과 같은 장점이 있다.

  • JOIN 을 제거하는 것이기 때문에 검색시간이 더 빨라진다.
  • JOIN 의 기술적 문제가 해결될 수 있다.

 

중복, 통합 등이 발생할 수 있으므로 다음과 같은 단점이 발생할 수 있다.

  • 데이터의 삽입, 수정, 삭제 등의 비용이 높아진다.
  • 중복, 통합은 많은 저장 공간이 요구된다.

 

반응형