본문 바로가기
SQLD

[SQLD] 정규화의 필요성

by DUSTIN KANG 2024. 3. 2.

정규화는 왜 생겨났을까?

한 릴레이션에 두 개 이상의 속성(Attribute)가 혼합하게 되면 중복 저장으로 인해 공간을 낭비하게 된다. 

좋은 관계형 데이터베이스를 설계하기 위해 이상 현상(Anomaly)이 생기지 않게 설계를 해야하는데 이 이상 현상이 테이블 내에 중복성으로 인해 생기는 데이터 불일치 현상이다.  이상 현상에는 삽입 이상, 삭제 이상, 갱신 이상이 존재한다.

  • 삽입 이상 : 테이블에 원치 않는 자료가 삽입된다는지, 자료가 부족해 삽입이 되지 않을 때 발생하는 문제점이다.
  • 삭제 이상 : 테이블에 자료를 삭제하고 싶은데 튜플의 전체 열을 삭제해야함으로 원치 않는 정보까지 삭제해야하는 현상이다.
  • 갱신 이상 : 테이블에 어떤 값을 업데이트 했을 때 다른 값들과 불일치가 발생하는 현상이다. 

 

정규화

정규화(Normalization)는 중복된 데이터를 줄여 무결성을 향상시키기 위해 데이터를 구조화하는 작업이라고 알게되었다. 

정규화 과정에는 1차 정규화부터 5차 정규화까지 존재하는데 정규화 과정을 거쳐야 정규형을 만족하게 된다. 각 정규화 과정마다 속성 간 함수적 종속성을 판단해 정규형을 정의하는 과정이다. 

 

OLTP 데이터베이스(거래 시스템)는 CRUD가 많이 일어나기 때문에 정규화 되는 것이 좋지만 OLAP와 같은 분석용 데이터베이스는 연산 속도가 중요하기 때문에 반정규화의 대상이 된다. 반정규화에 대해서는 후에 나올 예정이다.

함수적 종속성(Functional Dependency)
데이터(종속자)들이 어떤 기준 값(결정자)에 의해 종속되는 현상을 말한다.
ex) X(결정자)는 Y(종속자)를 함수적으로 결정한다.

 

제 1 정규형

어떤 테이블이 제 1 정규형을 만족했다는 것은 아래 조건을 만족했다는 것이다.

  • 속성의 도메인이 오직 원자 값만을 포함한다.
  • 튜플의 모든 속성이 하나의 값을 가져야 한다.
  • 기본 키를 사용해 데이터의 각 집합을 식별할 수 있어야 한다.

아래 테이블은 제 1 정규형을 만족하기 위해 제 1 정규화를 진행해야하는 것이다. 

행 단위 뿐만아니라 열 단위도 하나의 값을 가져야 한다.

제 2 정규형

어떤 테이블이 제 1 정규형에서 제 2 정규형을 만족하기 위해 다음 조건을 만족해야 한다.

  • 테이블의 모든 컬럼이 완전 함수적 종속을 만족해야 한다.
    • 기본 키 중 부분 집합키만 다른 컬럼을 결정지어선 안된다는 이야기이다.
    • 부분 함수 종속을 해결해야 한다.

아래 테이블은 제 2 정규형을 만족하기 위해 제 2 정규화를 진행하는 것이다.

다음, 테이블을 보면 학번(`USER_ID`)은 학생이름(`USER_NAME`)을 결정 짓는다.  (학변 → 학생 이름)

과목코드(`SUBJECT_ID`)는 과목 명(`SUBJECT_NAME`)을 결정 짓는다. (과목 코드 → 과목 명) 

그러나, 과목명은 학번과 연관이 없다. 그렇기 때문에 완전 함수적 종속을 만족하기 위해 테이블을 분리할 필요가 있다.

완전 함수적 종속(Full Functional Dependency)
속성 Y가 X 속성에 대해 함수적 종속이고 X의 다른 진 부분 집합에 함수적 종속이 아닐 때를 말한다.
이러한 경우, 부분 종속을 각 테이블로 나누어 완전 종속으로 만들어야 한다.
e.g. 성적은 학번과 과목번호에 의해 결정됩니다. (학번, 과목 번호 → 성적)

제 3 정규형

어떤 테이블이 제 2 정규형에서 제 3정규형을 만족하기 위해 다음 조건을 만족해야 한다.

  • 기본키가 아닌 속성들은 기본키에만 의존해야 하며 기본키가 아닌 속성들끼리 종속 관계를 가지면 안된다.
    • 이행적 종속을 해결해야 한다.

아래 테이블을 보면, 생년월일이 기본키가 아닌 속성인 이름에 종속(의존)된다는 것을 확인할 수 있다.

제 3정규형을 만족하기 위해 이 테이블을 둘로 나눠야 한다.  

이행 함수적 종속(Transitive Functional Dependency)
이행 함수적 종속은  X → Y, Y → Z의 종속 관계를 의미한다. 즉, 일반 속성(비주요 속성)이 일반속성에 의해 종속되는 경우다.

BCNF

BCNF(Boyce-Codd) 정규형은 테이블의 모든 결정자가 후보키일 경우 발생한다. 흔치 않는 경우이다.

식별자 관계가 복잡할 때 3정규형을 보완하는데 사용된다.

 


정규화의 장단점

장점

  • 앞에서 나왔듯 데이터의 중복성으로 인한 이상 현상을 해결할 수 있다.
  • 구조가 쪼개져 있다보니, 데이터 구조를 변경할 때 일부만 변경해도 된다는 장점이 있다.
  • 테이블 내 데이터 용량이 줄어들 수 있다.

단점

  • 테이블을 쪼개다보니 JOIN 연산이 많아질 수 있다. 이로 인해 SQL 성능이 저하될 수 있다는 단점이 있다.

결론적으로 테이블의 정규화를 진행하게되면 성능이 저하될 수 있고 더 좋아질 수 있기 때문에 항상 정규화가 좋다는 것은 아니다.


반정규화

반정규화(De-normalization)은 정규화된 테이블의 성능 향상 및 단순화를 위해 중복, 통합 혹은 분리를 수행하는 방법이다.

정규화로 인해 조회할 때 디스크 I/O량이 많아져 성능이 저하된다. 혹은 경로가 너무 멀어 많은 JOIN으로 인해 성능이 약해진다.

이로 인해 조회에 대한 성능을 향시키기 위해 반정규화 사용을 고려한다.

반정규화의 대상

  • 자주 접근하는 테이블이거나 항상 일정한 범위만 조회하는 경우 → 캐시를 사용해 성능을 향상시킨다.
  • 대량의 범위 데이터를 자주 처리하는 경우 → 클러스터링을 적용해 인덱스를 조정한다. 혹은 파티셔닝으로 분리한다.
  • 지나치게 많은 조인으로 인해 조회가 어려운 경우 → VIEW를 사용해본다. 하지만 성능은 향상되진 않는다.

반정규화의 적용

View나 캐시, 클러스터링, 파티셔닝 대체 방법을 사용해도 안된다면 반정규화를 적용한다. 

반 정규화의 종류로는 3가지가 존재한다.

  • 테이블 반정규화
    • 테이블 분할(수직 분할, 수평 분할)
      • 수직 분할 : 1개의 테이블을 2개의 테이블로 수직 분할 (USER - USER_DETAIL)
      • 수평 분할 : 스키마는 동일하지만 데이터 사이즈를 위해 분할 (1월 임금, 2월 임금...)
    • 테이블 병합
    • 테이블 추가 : 시간이 오래 걸리는 통계 데이터를 주기적인 BATCH JOB 을 이용해 별도 구성 (실시간 조회)
  • 컬럼 반정규화
    • 중복 컬럼 추가 : 자주 사용되는 컬럼을 중복으로 추가, 별도의 정합성 관리가 필요하다.
  • 관계 반정규화
    • 중복 관계 추가 : 조인을 여러 번해서 고객정보를 읽을 수 있지만, 접근 경로를 단축 시키기 위해서 중복관계를 추가함

반정규화의 단점

물론, 반 정규화가 성능을 향상시킬 수 있지만 과하게 적용하게 되면 데이터 무결성이 깨질 수 있다. 

'SQLD' 카테고리의 다른 글

[SQLD] 인덱스  (0) 2024.03.11
[SQLD] JOIN의 개념과 종류  (0) 2024.03.01
[SQL] 터미널로 MySQL, PostgreSQL 설치하기 (MacOS)  (0) 2024.02.27
[SQLD] 윈도우 함수  (0) 2024.01.27
[SQL/DB]NoSQL과 SQL는 무슨 차이가 있는 걸까?  (0) 2024.01.08