[ CS / DataBase ] 정규화

황승환·2022년 1월 20일
0

CS

목록 보기
14/60
post-thumbnail

정규화

정규화란 관계형 데이터베이스에서 데이터의 중복을 최소화하기 위해 데이터를 구조화 하는 작업을 의미한다. 데이터의 중복을 최소화하여 데이터 무결성을 유지하고 DataBase의 저장 용량 또한 효율적으로 사용할 수 있게 된다.

정규화가 아예 적용되지 않은 경우(데이터 중복이 많은 경우), 하나의 릴레이션에서만 A라는 정보를 A'로 바꾸게 되면 추후에 데이터를 조회할 때에 어떤 릴레이션에서는 A'로 되어 있고, 어떤 릴레이션에서는 A로 되어 있기 때문에 어떤 데이터가 맞는 데이터인지 알 수 없게 된다.

정규화의 등장 배경

하나의 릴레이션에 여러개의 엔티티의 애트리뷰트들을 혼합하게 되면 데이터 중복이 발생하고, 이로 인해서 저장 공간을 낭비하게 된다. 또한 데이터 중복은 갱신 이상 문제까지도 초래한다. 갱신 이상의 종류는 다음과 같다.

  • 삽입 이상
    원하지 않는 자료가 삽입되거나, 삽입 시 자료의 부족으로 삽입이 되지 않는 경우 발생하는 문제
  • 삭제 이상
    하나의 자료만 삭제하고 싶지만 그 자료가 포함된 튜플 전체가 삭제되어 원하지 않는 데이터 손실을 초래하는 문제
  • 수정(갱신) 이상
    정확하지 않거나 일부의 튜플만 갱신되어 정보가 모호하거나 일관성이 없어져 정확한 정보 파익이 되지 않는 문제

나쁜 릴레이션

엔티티를 구성하고 있는 애트리뷰트 간의 함수적 종속성을 판단하여 나쁜 릴레이션인지 좋은 릴레이션인지 판단한다. 판단된 함수적 종속성은 좋은 릴레이션 설계의 정형적 기준으로 사용된다. 이는 각각의 정규형마다 어떠한 함수적 종속성을 만족하는가에 따라 정규형이 정의되고 그 정규형을 만족하지 못할 경우에 나쁜 릴레이션으로 간주하게 된다.

함수적 종속성

함수적 종속성이란 애트리뷰트 데이터들의 의미와 애트리뷰트들 간의 상호 관계로부터 유도되는 제약조건의 일종이다. 예를 들어, 어떤 릴레이션 안에 X와 Y를 각각 속성의 부분 집합이라고 가정할 때, X의 값을 알면 Y의 값을 바로 식별할 수 있고 X의 값에 의해 Y의 값이 변경될 때 "Y는 X에 함수적 종속한다." 또는 "X는 Y를 함수적 결정한다."라고 한다. 이 경우 X를 결정자, Y를 종속자라고 한다. 이를 기호로 표현하면 X->Y가 된다.

정규화의 종류

정규화는 1차 정규화, 2차 정규화, 3차 정규화, ... 등이 있으며 보통은 3차 정규화까지만 진행한다.

1차 정규화

애트리뷰트의 도메인이 오직 원자값만 포함해야 하고, 튜플의 모든 애트리뷰트가 도메인에 속하는 하나의 값을 가져야 한다. 이는 복합 애트리뷰트, 다중값 애트리뷰트, 중첩 릴레이션 등의 비원자적인 애트리뷰트를 허용하지 않는 릴레이션의 형태이다.

예를 들어 학생이라는 엔티티에 취미라는 애트리뷰트가 있다고 가정해보자. A학생은 취미가 축구와 게임이라고 한다면 1차 정규화를 하기 전의 형태에서는 다음과 같이 들어간다.

학번	이름	주소	취미
1111	A	서울	축구, 게임

그러나 이는 매우 위험한 형태이므로 1차 정규화가 진행되어야 한다. 1차 정규화가 적용되면 다음과 같은 형태가 된다.

학번	취미	이름	주소	
1111	축구	A	서울
1111	게임	A	서울

1차 정규화를 통해 컬럼이 원자성을 가지는 것을 볼 수 있지만 여기에는 데이터의 중복이 발생하고 있다.

2차 정규화

1차 정규화를 진행한 엔티티에 대해 완전 함수 종속을 만족하는 테이블을 분해하는 것이다. 모든 비주요 애트리뷰트들이 주요 애트리뷰트에 대해 완전 함수적 종속이면 2차 정규화를 만족한다고 할 수 있다. 완전 함수적 종속이란 X->Y라고 했을 때, X에 대한 어떠한 애트리뷰트라도 제거하면 더 이상의 함수적 종속성이 성립하지 않는 경우를 말한다.

간단하게 말하면 기본키 중 특정 컬럼에만 종속된 컬럼이 없어야 한다.

학번	취미	이름	주소	
1111	축구	A	서울
1111	게임	A	서울

1차 정규화를 마친 모습이다. 위의 엔티티를 보면 이름과 주소의 경우에는 학번에만 종속되어 있다. 이는 학번의 값을 알면 이름과 주소에 대한 값을 알 수 있으므로 이름, 주소가 2번이나 입력되는 것은 불필요한 과정이다. 그렇기 때문에 취미 엔티티를 따로 분리시켜 2차 정규화를 진행해야 한다.

학생
학번	이름	주소
1111	A	서울

취미
학번	취미
1111	축구
1111	게임

3차 정규화

2차 정규화를 진행한 엔티티에 대해 이행적 종속을 없애도록 엔티티를 분해하는 것이다. 이행적 종속은 A->B, B->C일 경우 A->C가 성립되도록 하는 것이다. 이는 쉽게 말해서 기본키 이외의 다른 컬럼이 그 외의 다른 컬럼을 결정할 수 없다는 것을 의미한다.

학생
학번	이름	주소	도시코드
1111	A	서울	001

취미
학번	취미
1111	축구
1111	게임

2차 정규화가 완료된 상태이다. 학생 엔티티를 보면 주소와 도시코드가 같이 쓰인 것을 볼 수 있다. 주소와 도시코드 모두 기본키는 아니지만 도시코드에 의해 주소가 정해지는 것을 볼 수 있다. 이는 3차 정규화를 통해 다른 엔티티로 관리할 수 있다.

학생
학번	이름	도시코드
1111	A	001

취미
학번	취미
1111	축구
1111	게임

도시
도시코드	도시명
001	서울
002	경기
003	인천

이렇게 도시코드를 키로 사용하여 도시를 결정할 수 있게 되었다. 또한 3차 정규화를 통해서 데이터의 중복을 감소시켰다.

BCNF(Boyce-Codd Normal Form)

3차 정규화가 적용된 엔티티에 대해 모든 결정자가 후보키가 되어 엔티티를 분해하는 것을 말한다. 이는 함수 종속이 아닌 다중값 종속성을 제거하는 것이다. 복잡한 식별자 관계에 의해 발생하는 문제를 해결하기 위해 3차 정규화를 보완하는 과정이다.

학번	과목	이름	교수	학점
1111	OS	A	a	A+
1111	DB	A	b	A
1112	OS	B	a	B+

위의 엔티티의 기본키는 학번, 과목이다. 학번, 과목은 교수를 결정짓고, 교수는 과목을 결정짓는다. 여기서 교수는 결정자지만 후보키가 아니라는 문제가 발생한다. 이 경우에 과목이 변경될 경우 교수도 따로 변경해줘야 데이터 무결성이 유지된다.

학생
학번	과목	이름	학점
1111	OS	A	A+
1111	DB	A	A
1112	OS	B	B+

교수
교수	과목
a	OS
b	DB

이렇게 엔티티를 나눠 BCNF화 할 수 있다.

각 정규화 특징

각각의 정규화는 이전 정규화보다 더 엄격한 조건을 가진다.

  • 2차 정규화는 1차 정규화를 만족해야함.
  • 3차 정규화는 2차 정규화를 만족해야함.
  • BCNF는 3차 정규화를 만족해야함.

관계형 데이터베이스 설계의 목표는 3차 정규화 혹은 BCNF에 있다.

정규화의 장단점

장점

  • 데이터베이스 내에 있는 데이터 변경 시 데이터의 중복으로 인해 발생할 수 있는 무결성 문제 등을 해결할 수 있다.
  • 정규화된 데이터베이스 구조를 확장할 때에 그 구조를 변경하지 않아도 되거나 일부만 변경해도 된다. (데이터베이스와 연동된 애플리케이션에 최소한의 영향만을 주어 애플리케이션의 생명을 연장)
  • 정규화된 테이블들과 정규화된 테이블 간의 관계들은 현실에서의 개념들과 그 관계들을 반영하여 사용자에게 데이터 모델을 더욱 의미있게 제공한다.

단점

엔티티의 분리로 인해 엔티티 간의 관계들이 많이 생기게 되고 당연히 SELECT 연산을 할 때에 JOIN이 많아진다. 이는 심할 경우 성능에 안좋은 영향을 준다.

정리

정규화를 수행하는 것은 데이터를 결정하는 결정자에 의해 함수적 종속을 가지고 있는 일반 속성을 종속자로 만들어 입력/수정/삭제 연산 이상을 제거하는 것이다.

데이터의 중복 속성을 제거하고 결정자에 의해 동일한 의미의 일반 속성이 하나의 테이블로 집약되기 때문에 한 테이블의 데이터 용량을 최소화하는 효과가 있다. 정규화된 테이블은 데이터 처리 시 속도가 빨라질 수도 있고, 느려질 수도 있다.

그렇기 때문에 무조건 정규화를 하기보다는 주요 연산이 무엇인지, 어떤 기능을 하는지 등을 잘 생각하여 적당한 정규화와 반정규화를 섞는 것이 성능에 가장 좋다.

반정규화

정규화된 엔티티, 속성, 관계를 시스템의 성능 향상, 개발과 운영의 단순화 목적으로 중복 통합, 분리 등을 수행하는 데이터 모델링 기법이다. 디스크 I/O량이 많아져 조회의 성능이 떨어지거나, JOIN 연산이 많아져 조회의 성능 저하가 예상되거나, 컬럼의 값을 계산하여 값을 도출해야 하는 경우에 성능 저하가 예상될 때에 반정규화를 수행한다. 일반적으로 조회의 성능이 중요하다고 여겨질 때에 반정규화를 진행한다.

컬럼의 값을 계산하여 값을 도출해야 하는 경우는 어떤 것이 있을까? 예를 들면 다음과 같다.

주문 테이블이 있다고 하면 물건의 코드명과 수량이 입력될 것이다. 이때 총 금액을 조회마다 계산하여 도출하는 방법(정규화)과 총 금액을 미리 계산하고 엔티티에 총액 속성을 만들어 저장하고 단순 조회하는 방법(반정규화)가 있다. 이렇게 계산을 계속 해야하는 경우에는 이 부분에 대해서만이라도 반정규화를 적용하는 것이 성능에 좋다.

반정규화 대상

  • 자주 사용되는 테이블에 접근하는 프로세스 수가 가장 많고 항상 일정한 범위만 조회하는 경우
  • 테이블에 대량 데이터가 있고 대량의 범위를 자주 처리하는 경우, 성능 상의 문제가 있을 경우
  • 테이블에 지나치게 많은 조인이 사용되어 데이터 조회하는 것이 기술적으로 어려울 경우

반정규화 주의점

반정규화를 너무 과도하게 적용할 경우 데이터 무결성이 깨질 수 있고, 테이터의 입력, 수정, 삭제 연산 성능이 저하될 수 있기 때문에 적당한 반정규화가 중요하다.

profile
꾸준함을 꿈꾸는 SW 전공 학부생의 개발 일기

0개의 댓글