DB

[데이터베이스] 정규화와 반정규화

Sigfriede 2023. 12. 21. 12:10

  정규화(normalization)란 ERD 내에서 중복을 찾아 제거해 나가는 과정이다. 관계형 데이터베이스에서 동일한 정보는 한 곳에서만 관리해야 한다. 동일한 정보가 여러 곳에 중복하여 존재하면 정보가 일관되지 않는 등 여러 문제가 발생한다. 이론적으로는 5차 정규화까지 있지만, 대부분 3차 정규화까지만 실행한다.

  정규화된 데이터 모델은 일관성, 정확성, 단순성, 비중복성, 안전성 등을 보장한다. 정규화 수준이 높을수록 유연한 데이터 구축이 가능하고 데이터의 정확성이 높아지는 반면 물리적 접근이 복잡하고 너무 많은 조인으로 인해 조회 성능이 저하된다.

  정규화를 잘할 수 있게 되는 것도 중요하지만 정규화가 필요 없도록 모델링을 하는 것이 더 바람직하다. 실제로 정규화를 잘 이해하고 있는 설계자는 정규화를 할 필요가 없도록 모델링을 한다.

 

제1정규화

  엔티티에서 하나의 속성이 복수의 값을 갖도록 설계되었을 때 하나의 속성이 단일 값(atomic value)을 갖도록 하는 것이다. 예를 들어 학생 한 명이 여러 강의를 수강할 때, 수강 속성에 각 강의를 구분하지 않고 저장하는 상황에서는 복수의 값이 한 속성에 저장되면 각각의 값을 구분하기 어렵다.

학생번호(PK) 수강
1 강의1
강의2
강의3
2 강의3
3 강의1
강의2

  다음과 같이 각 학생번호별, 수강별 구분하여 값을 저장해야 한다.

학생번호(PK) 수강(PK)
1 강의1
1 강의2
1 강의3
2 강의3
3 강의1
3 강의2

 

  또는 다음과 같이 수강1, 수강2, 수강3처럼 반복 속성을 이용하여 설계하는 상황에서는 데이터가 저장되지 않은 빈 곳이 많이 발생할 수 있고, 수강4를 저장해야 할 경우 속성을 하나 더 늘려야 하는 문제가 있다.

학생번호(PK) 수강1 수강2 수강3
1 강의1 강의2 강의3
2 강의3    
3 강의1 강의2  

  정규화시 반복 속성에 해당하는 속성을 위해 별도의 엔티티를 만들고, 기존 엔티티와 관련성을 유지하기 위해 별도의 엔티티에 외래식별자를 갖는다.

 

제2정규화

  주식별자가 아닌 속성 중에서 주식별자 전체가 아닌 일부 속성에 종속된 속성을 찾아 제거하는 과정이다. 제거란 다른 엔티티를 만들어 속성을 옮기는 것이다. 별도의 엔티티에 저장하고 엔티티에서는 이를 참조하는 방식으로, 중복된 데이터 사이에 불일치가 발생할 수 있는 문제를 해결한다.

 

제3정규화

  주식별자가 아닌 속성들 중에서 종속 관계에 있는 속성을 찾아 제거하는 과정이다.

 

제4정규화

  테이블에 다치 종속(A, B, C 3개의 속성을 가진 테이블에서 어떤 복합 속성(A, C)에 대응하는 B 값의 집합이 A 값에만 종속되고 C 값에는 무관하면 B는 A에 다치 종속이라 하고 A->>B로 표기) A->>B가 성립하는 경우 관계의 모든 속성이 A에 함수적 종속(데이터가 어떤 기준값에 의해 종속되는 것) 관계를 만족한다.

 

제5정규화

  테이블의 모든 조인 종속(어떤 테이블의 속성에 대한 부분집합 A, B, …, C가 있을 때 테이블이 자신의 속성 A, B, …, C를 모두 조인한 결과가 자신과 동일한 경우 조인 종속을 만족한다고 함)이 후보키를 통해서만 성립한다.

 

반정규화

  반정규화(de-normalization)는 정규화와 대비되는 개념으로 정규화가 데이터 무결성 유지에 있다면 반정규화의 목적은 반대로 어느 정도의 중복은 감수하고 데이터베이스의 성능(특히 검색 속도)을 향상시키는 것에 있다. 정규화 과정이 엔티티를 분리하는 형태로 진행한다면, 반정규화 과정은 엔티티를 통합하는 형태로 진행한다. 데이터베이스는 정보를 올바르게 관리하는 것도 중요하지만 다수 사용자가 동시에 이용할 때 성능을 유지하는 것도 중요하다.

 

엔티티의 통합/분할에 의한 반정규화

  조인에 의한 검색을 하고, 검색이 빈번히 이루어지는 엔티티를 대상으로 한다. 엔티티를 통합하면 조인 연산에 걸리는 시간을 단축할 수 있기 때문에 검색 성능의 향상을 기대할 수 있다.

  경우에 따라 엔티티를 분할함으로써 반정규화를 할 수 있다. 엔티티의 튜플 수 및 속성의 수가 매우 많고, 엔티티의 속성들이 그룹화되어 각 그룹이 특정 부서 혹은 응용 프로그램에 의해서만 사용될 때, 엔티티를 수직분할 할 수 있다. 데이터량을 줄임으로써 성능 향상을 도모한다.

  경우에 따라 튜플의 조회 빈도를 기준으로 수평분할을 하기도 한다. 자주 검색되는 튜플과 그렇지 않은 튜플을 구분하여 저장하면 자주 검색되는 튜플에 대해서는 검색 속도가 향상된다. 응용 프로그램에서는 먼저 자주 검색되는 튜플에서 검색을 하고 없으면 그렇지 않은 튜플에서 검색을 하도록 한다. 엔티티를 수평분할하면 두 엔티티의 속성은 동일하고 아무 관계도 성립하지 않는다.

 

속성의 중복에 의한 반정규화

  조인하여 가져다 사용하는 속성의 수가 적을 때는 엔티티의 통합은 비효율적이다. 조인에 의해 가져오는 속성을 중복해서 저장하는 편이 더 합리적이다. 이렇게 하면 조인을 하지 않아도 정보를 알 수 있다.

 

관계에 대한 반정규화

  속성의 중복에 의한 반정규화와 비슷하다. 차이점은 중복을 하는 속성이 다른 엔티티와의 관계를 맺어주기 위한 외래키로 사용된다는 것이다. 알고자 하는 정보가 조인 경로가 복잡하여 연쇄적으로 조인해야만 정보를 알 수 있을 때, 반정규화하여 중간 경로를 거치지 않고 바로 조인하여 정보를 알 수 있다.

 

  ※ 데이터베이스 설계 및 구축(오세종)을 참고하여 작성한 글입니다. 참고자료에는 게시글보다 상세하고 정확한 설명이 기재되어 있습니다. 이 게시글에  문제가 되거나 부정확한 부분이 있다면 알려주시면 감사하겠습니다.