테이블 설계의 기초(테이블 및 정규화)

WOOK JONG KIM·2023년 1월 31일
0

DB첫걸음

목록 보기
8/10
post-thumbnail

테이블 설계에서 중요한 것은 집합함수

관계형 데이터에서 데이터를 관리하고 저장하기 위한 그릇은 테이블뿐!
-> 업무에 필요한 데이터는 매우 다양하며 이를 관리하기 위한 DB의 테이블 수도 수백개~수천개 존재
-> 설계를 제대로 하지 않을 시 데이터가 어디에 있는지도 알기 힘들고, 장기적 운용도 견디지 못함(데이터 모순이 생기기도 함)

시스템에서는 DB에 저장된 데이터가 전부라서 이것이 잘못 된 경우에는 이에 기반을 둔 모든 처리 결과가 부정확해짐
-> 따라서 DB는 매우 높은 수준의 정합성이 요구됨
-> 관계형 DB는 데이터의 정합성을 높이기 위한 설계 노하우가 매우 발달하였음

테이블 설계는 서버나 스토리지와 같은 물리층과 관계없이 독립적으로 작성하는 것이 가능해서, 논리의 세계에서 결정된다고 간주

테이블은 열과 행으로 구성된 데이터 구조
-> 관계형 DB에 있어서 테이블은 공통적인 요소의 집합이라는 개념 중요
-> 즉 관련성이 없는 것이 모여서는 안된다는 의미

관계형 DB에서 테이블은 어떤 공통의 속성을 가진 것의 집합(테이블 제1 규칙)
-> 테이블명은 반드시 복수형이나 집합명사로 표현해야 함

또한 테이블은 현실 세계를 반영
-> 현실 세계의 개념이나 집합을 나타낸 것

은 개체의 속성
-> Java 입장에서 이해해보자면, 테이블은 클래스에 해당하고 각 행은 거기서 실체화된 instance에 해당됨
-> 다만 테이블은 테이블 정의에서 메서드를 가지고 있지 않아, 자신이 주체적으로 액션을 일으키지 않고 단지 조작을 받는 수동적인 존재
-> 즉 메소드를 뺀 클래스 느낌

테이블 설계 원칙의 하나로 반드시 기본키를 설정할 것이라는 원칙이 존재
-> 한개의 테이블의 내용에는 중복 행을 허용하지 않는다라는 의미
-> 나이나 성별이 일치하거나, 동성동명인 사람의 데이터가 존재할 수 있지만, 행 자체가 완전히 같은 데이터가 있다면 이 행이 어떤 것과 대응하는 것인지 알기 어려움
-> 이를 막기 위해 RDB에서의 테이블은 반드시 레코드를 1개의 행으로 특정할 수 있는 정보가 필요(ex : 회원 ID, 회원번호)

기본키로 사용하는 열은 중복이 발생하지 않는 값을 할당해야 함
-> 만약 이후에 기본키가 변경된다면 과거 데이터와 매칭이 어려울 뿐 아니라, 변경 후 값의 유일성을 보증할 수 없음(ex: A라는 이름을 가진 사람이 이후 A1이라는 이름으로 개명하였는데, A1이라는 사람이 이미 등록된 경우, 이러한 이유로 이름은 기본키로 잘 사용하지 않음)
-> 즉 테이블은 데이터가 정적이지 않고 동적임을 전제로 생각해야 함
-> 과거 이력 데이터 같은 것이 담겨있는 테이블은 정적이기 때문에 데이터 관리가 비교적 느슨하거나, 정규화를 그다지 엄격하게 수행하지 않아도 됨

기본키 열에는 NULL이 존재해서는 안됨
-> 기본키가 NULL이라면 이 행에 매칭되는 대상을 찾는것이 어려울 것임


정규형

테이블을 정의할때 기본이 되는 것이 정규형

정규형이란 데이터의 갱신이 발생한 경우에도 부정합이 발생하기 어려운 테이블의 형태 의미
-> 1에서 5정규형 까지 존재하며 3정규형 까지 파악하는 것만으로 충분

제1정규형(1NF)

테이블의 컬럼이 원자값(Atomic Value, 하나의 값)을 갖도록 테이블을 분해하는 것
-> 관계형 DB에서는 이 정의에 반하는 테이블을 작성하는 것이 기술적으로 불가능

관계형 데이터베이스에서 복합적인 값을 셀에 넣으면 안됨
-> 만약 복합적인 값을 허용하면 기본키가 있는 행의 값을 고유하게 특정할 수 없기 때문
-> 즉 기본키를 특정하면 어떤 레코드의 열 값 전체가 고유하게 특정된다는 의미
-> 기본키와 그 외의 열 사이에는 함수적인 관계가 있다
-> 즉 관계형 DB의 테이블은 기본키 -> 입력값, 열값 -> 출력값으로 간주하는 느낌

제2정규형(2NF)

제1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것
-> 여기서 완전 함수 종속이라는 것은 기본키의 부분집합이 결정자가 되어선 안된다는 것

이 테이블에서 기본키는 (학생번호, 강좌이름)으로 복합키
그리고 (학생번호, 강좌이름)인 기본키는 성적을 결정하고 있음 (학생번호, 강좌이름) --> (성적)
그런데 여기서 강의실이라는 컬럼은 기본키의 부분집합인 강좌이름에 의해 결정될 수 있음 (강좌이름) --> (강의실)

즉, 기본키(학생번호, 강좌이름)의 부분키인 강좌이름이 결정자이기 때문에 위의 테이블의 경우 다음과 같이 기존의 테이블에서 강의실을 분해하여 별도의 테이블로 관리하여 제2 정규형을 만족시킬 수 있음

제3정규화(3NF)

제3 정규화란 제2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것

여기서 이행적 종속이라는 것은 A -> B, B -> C가 성립할 때 A -> C가 성립되는 것을 의미

기존의 테이블에서 학생 번호는 강좌 이름을 결정하고 있고, 강좌 이름은 수강료를 결정하고 있음
-> 그렇기 때문에 이를 (학생 번호, 강좌 이름) 테이블과 (강좌 이름, 수강료) 테이블로 분해해야 함

이행적 종속을 제거하는 이유는 비교적 간단
-> 예를 들어 501번 학생이 수강하는 강좌가 스포츠경영학으로 변경되었다고 하자. 이행적 종속이 존재한다면 501번의 학생은 스포츠경영학이라는 수업을 20000원이라는 수강료로 듣게 된다. 물론 강좌 이름에 맞게 수강료를 다시 변경할 수 있지만, 이러한 번거로움을 해결하기 위해 제3 정규화를 하는 것
-> 즉, 학생 번호를 통해 강좌 이름을 참조하고, 강좌 이름으로 수강료를 참조하도록 테이블을 분해해야 함

일련의 수정 절차를 줄이거나 간편하게 하기 위해 사용

BCNF

제3 정규화를 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 테이블을 분해하는 것

특강수강 테이블에서 기본키는 (학생번호, 특강이름), 그리고 기본키 (학생번호, 특강이름)는 교수를 결정
-> 또한 이 테이블에서 교수 테이블은 특강이름을 결정함
-> 그런데 문제는 교수가 특강이름을 결정하는 결정자이지만 후보키가 아니라는 점, 그렇기 때문에 BCNF 정규화를 만족시키기 위해서 위의 테이블을 분해해야 함

갱신 이상의 위험을 없애기 위해 정규화를 수행하면, 테이블이 나누어져 그 수가 증가
-> 많은 테이블의 관계성은 파악하기 어렵기 때문에 , 테이블 간에 관련성을 한눈에 알수 있게 고안된 기술이 ER Diagram

외래키는 해당 열이 다른 테이블의 기본키 열을 참조하는 것


profile
Journey for Backend Developer

0개의 댓글