[정규화] 효율적인 데이터베이스 스키마 구축 2

2020. 6. 17. 15:32컴퓨터언어/Database

728x90
반응형

2020/06/16 - [컴퓨터언어/Database] - [정규화] 효율적인 데이터베이스 스키마 구축

 

[정규화] 효율적인 데이터베이스 스키마 구축

"효율적"인 데이터베이스가 무엇일까? 개념적 설계를 통해 <학생>이라는 개체에 필요할 만한 속성을 이것저것 넣었다고 해보자. 학번, 이름, 주민번호, 성별, 주소, 학과, 동아리, 학점, ...... 너무

an-onymous.tistory.com

이전 글에서 정규화는 개념적 설계로 나온 ER 다이어그램을 보편적인 "관계형 테이블"로 대응시킴과 동시에, 효율적인 데이터베이스를 만들기 위한 "논리적 설계" 과정이라고 하였다.

만약 정규화 없이 단순히 개념적 설계만을 가지고 데이터베이스화 한다면 삽입/삭제/갱신 이상이 발생할 것이기 때문이다.

 

정규화의 목적을 다시 한번 정리해본다.

  • 데이터 구조의 안정성 최대화(한번 정제하기 때문)
  • 데이터베이스의 가장 큰 적인 "중복"을 배제하여 삽입/삭제/갱신 이상의 발생을 방지
  • 어떠한 릴레이션이라도 데이터베이스 내에서 표현 가능하도록 함
  • 데이터 삽입 시 릴레이션을 재구성할 필요성을 줄임
  • 효과적인 검색 알고리즘을 생성

이처럼 정규화를 거친 릴레이션은 향후 데이터베이스 관리와 기타 개발에 큰 도움을 준다.


그렇다면 정규화 과정을 알아보자

 

<아직 정규화를 하지 않았다면>
그 릴레이션을 "비정규 릴레이션"이라고 부른다.
정규화를 한번도 시행하지 않은 ER 스키마 그 자체로, 삽입/삭제/갱신 이상(Anamoly)이 발생한다.

 

정규화는 제1정규형부터 차례대로 제5정규형까지 진행되며, 실무에서는 주로 3.5정규형에 해당하는 BCNF까지만 쓰인다.

정규화의 원리 : 데이터베이스 안의 각 개체는 하나의 주제만을 담고 있어야 한다.
<학생>이라는 개체에는 학생에 꼭 필요한 속성들만 담아야지, 사족을 붙이지 말자는 얘기다.
쓸데없는 속성이 있었다면, 그것을 정리하는 것이 정규화다.
Every entity in your database needs to have a single theme

Edgar Codd

제1정규형 : 릴레이션에 속한 모든 도메인은 원자값을 가져야 한다.

 

원자값이란 더 이상 쪼개지지 않는 것을 의미한다. 컴퓨터에서의 비트처럼 말이다.

그런데 데이터베이스 세계에서는 속성을 더 이상 쪼갠다는 것이 의미가 없다. 예를 들어 주민번호 속성이라면, 앞/뒷자리로 다시 나눌 수 있고, 이름이라면 성씨로 다시 한번 나눌 수 있기 때문이다.

 

Edgar Codd의 정의가 이러한 혼란을 야기할 수 있기에, 크리스토퍼 J 데이트 박사는 1정규형의 정의를 다시 내렸다.

  • 열에는 위/아래의 순서가 없다.
  • 행에는 좌/우의 순서가 없다.
  • 중복되는 열이 없다.
  • 모든 열과 행의 중복지점에는 하나의 값만 들어있다.(한 칸에 한 개의 값만 들어있어야 한다는 것)
  • 모든 행은 규칙적이다.(행과 열의 라벨에 맞게 입력해야 한다는 것)

 

정리하면, 어떤 릴레이션에 다중값을 가진 속성이 있다면 그 릴레이션은 비정규 릴레이션이다.

이때 그 속성을 다른 테이블로 분할한 뒤, 외래키를 사용하여 기존 테이블을 참조시키면 제1정규형을 만족하게 된다.


제2정규형 : 1정규형을 만족하는 릴레이션에서 Key를 제외한 모든 속성들은 완전함수적종속으로만 이루어져야 한다.

제2정규형은 일단 1정규형부터 만족해야 한다.

그리고 복합키가 아니라 하나의 속성만으로 Key가 구성된 릴레이션은 부분함수적종속이 있을 수 없으므로, 모두 제2정규형을 만족한다.

복합키로 구성된 릴레이션이라면, 그 복합키 전체를 사용했을 때 하나의 속성을 결정할 수 있어야지, 복합키 중 일부의 키로도 하나의 속성을 결정할 수 있다면 제2정규형을 만족하지 않는다는 것이다(이것을 부분함수적종속이라고 한다).

*복합키로 구성되야 하는 경우는, 해당 릴레이션의 튜플들에 중복값이 많아 하나의 속성만으로는 키를 구성할 수 없을 때이다.


제3정규형 : 1, 2정규형을 만족하는 릴레이션에서 Key를 제외한 모든 속성들은 기본키에 이행적으로 종속될 수 없다.나 너 좋아해, 근데 넌 걜 좋아한다고? 그럼 나도 걔 좋아할래 각자 한놈만 파라

 

속성 A가 결정자로서 속성 B를 하나만 식별할 수 있고, 속성 B역시 결정자로서 또다른 속성 C를 하나만 식별할 수 있다면,

그 릴레이션은 A&B 와 B&C로 쪼개야 한다.


제3.5정규형(BCNF) : 1, 2, 3정규형을 만족하는 릴레이션의 모든 결정자는 후보키(유일성+최소성 만족)여야 한다.

Boyce박사와 Codd박사의 이름을 땀

 

3.5까지 오면 개념이 섞이고 헷갈릴 수 있으니 다시 한번 짚고 넘어간다.

지금 우리가 무엇을 하고 있나?
정규화다.
정규화는 관계형 DB를 "효율적"으로 가공하는 과정이며, 여기서 효율적이라는 것은 크고 무거운 테이블을 작고 가벼운 여러 테이블로 쪼갬으로써 이상현상을 방지하는 것이다.
이때 그냥 막 쪼개는 것이 아니라, 한 테이블 안에 여러 속성들이 현재 서로 어떤 종속성을 가지고 있으며, 그래서 그 종속성을 어떻게 배제시킬 것인가의 문제가 정규화이자 정규형이다.(정규화는 각 상위 단계로의 이동을, 정규형은 해당 단계를 만족하는 형태를 의미)
예를 들어 <학생> 테이블에 ["학번", "이름", "동아리", "학년", "수강과목", "주민번호"] 속성이 스키마로 되어 있다고 해보자.(밑줄이 기본키)
지금은 자료가 없어서 이 학생 개체의 인스턴스들이 모두 단일값만 갖고 있는지 알 수 없기에, 원자값을 가져 1정규형은 만족하고 있다고 가정하고 출발하자.
그런데 이 테이블은 현재 "학번"과 "주민번호"가 복합키로 구성되어 있지만, 둘 중 하나만으로도 "이름"을 하나씩 식별해낼 수 있기 때문에  2정규형을 만족하지 못한다(부분함수적종속 발생).
따라서 테이블을 ["학번", "이름", "동아리", "학년", "수강과목"]과 ["학번", "주민번호"] 같이 나누어 완전함수적종속화하여 2정규형으로 만들 수 있다.
그런데 이번에는 왼쪽 테이블을 보자.
"학번"을 안다면 그 학생의 "수강과목"을 알 수 있고, "수강과목"은 보통 학년제한이 있기 때문에 수강생의 "학년"도 알 수 있다.
즉 "학번"만 알면 "수강과목"이 징검다리가 되어 그 학생의 현재 학년도 알 수 있게 되는 것이다.
이를 이행함수적종속이라고 하고, 3정규형을 만족시키지 못하는 이유가 된다.
따라서 이 테이블을 다시 ["학번", "이름", "동아리"]와 ["학번", "수강과목", "학년"]으로 나누면 3정규형을 만족시킬 수 있게 된다.

 

3정규형은 지금까지 이렇게 많은 과정을 거친 엄청 아름다운 테이블이다.

하지만 3.5정규형까지 만족하려면, 3정규형까지 만족한 테이블의 "결정자(속성들 중 자신을 제외하고 단 하나의 속성을 조회해낼 수 있는 것)"는 후보키여야 한다는 조건이 필요하다.

예를 들어 복합키로 구성된 테이블의 기본키{A, B}가 결정자로서 C를 결정한다고 해보자.

이때 만약 C가 B를 결정할 수 있다면 어떻게 될까?

그럼 A, B는 후보키로서의 의미가 없게 된다. C만 이용해도 A나 B를 결정할 수 있는 것을, 뭣하러 {A, B}를 복합키로 묶어서 힘들게 결정자로 이용하는가? 이는 최소성을 위배하는 것이다.

 

따라서 3.5정규형을 만족시키려면, 해당 테이블을 A&C 와 C&B로 쪼개면 된다.


4, 5정규형은 이전 포스팅으로 대신한다.

2020/06/16 - [컴퓨터언어/Database] - [정규화] 효율적인 데이터베이스 스키마 구축

728x90
반응형