ERD 중요성

ERD 같은거 메인으로 유지하고 있는게 꼭 필요하겠다.

스키마 변경이나 테이블 추가 같은거 할 때 이 ERD 수정하고 반영할 수 있도록.

 

이게 없으면 기존 구조를 파악하기가 어렵고, 구조가 한 눈에 안들어오다보니 새로운 컬럼이나 테이블을 추가하면서 역정규화 되거나, 같은 내용의 컬럼이 서로 다른 테이블 2개에 각각 생성되거나 한다.

 

이렇게 되면 갱신이상 등 데이터 불일치가 발생할 여지가 생긴다.

또한 이런 식으로 테이블 막 추가하다 보면 돌이킬 수 없어짐... 나중에 정규화 하려고 했는데 기존 레코드를 싹 다 복사해서 2개로 나눠주어야만 한다거나...

 

ER 스키마 >> 릴레이션 사상

간단한 요소에서 복잡한 요소 순으로 사상한다.

  • 단계 1: 정규 엔티티 타입
  • 단계 2: 약한 엔티티 타입
  • 단계 3: 2진 1:1 관계 타입
  • 단계 4: 정규 2진 1:N 관계 타입
  • 단계 5: 2진 M:N 관계 타입
  • 단계 6: 3진 관계 타입
  • 단계 7: 다치 애트리뷰트

 

정규화 Normalization

정규화란 무엇이고 왜 하나?

  • 정규화란, 릴레이션 스키마를 함수적 종속성과 기본키를 기반으로 분리하는 것.
  • 데이터 중복과 [수정, 삽입, 삭제] 이상을 최소화 하기 위해 수행함
    • 보통 데이터 중복 -> 갱신 이상으로 이어지는 경우가 많음.
  • 세 가지 갱신 이상?
    • 수정 이상 : 데이터가 중복되어 모든 항목을 일괄 수정하지 않으면 데이터 불일치가 발생
    • 삽입 이상 : 불필요한 정보를 함께 저장하지 않고는 어떤 정보를 저장하는 것이 불가능
    • 삭제 이상 : 유용한 정보를 함께 삭제하지 않고는 어떤 정보를 삭제하는 것이 불가능

 

결정자와 함수적 종속성

결정자 (determinant)

  • 쉽게 생각해서 A로 검색했을 때 B가 모두 같은 값이 나온다면, A는 B의 결정자다.
    • 사원번호 4257로 검색하면 이름 "가나다"만 나온다.
    • 사원번호 4257인 사원의 이름이 "가나다"인 동시에 "이말년"일 수는 없음.
    • 따라서 사원번호는 이름의 결정자다.
  • 즉 A값에 대응되는 B가 꼭 하나여야 한다는 것인데
  • 반대로 B값에 대응되는 A는 여러개여도 상관 없다.
    • 사원번호 4257 이름 "가나다"
    • 사원번호 3215 이름 "가나다"
  • 결정자 A는 여러 애트리뷰트로 구성될 수 있음 (복합키 같이)
  • 결정자는 추후 분해된 릴레이션의 기본키가 될 수 있다.

 

함수적 종속성

  • A가 B의 결정자이면 B가 A에 함수적으로 종속한다. 라고 말함.
  • 완전 함수적 종속성
    • 해당 릴레이션의 모든 결정자를 사용해야만 1가지 값으로 결정되는 경우를 완전 함수적 종속성
    • 모든 결정자를 써야만 함수적으로 종속하는 경우
  • 부분 함수적 종속성
    • 해당 릴레이션의 일부 결정자를 사용해도 1가지 값으로 결정할 수 있는 경우 부분 함수적 종속성
    • 일부 결정자를 써도 함수적으로 종속하는 경우

완전 함수적 종속성과 부분 함수적 종속성 차이

  • 이행적 함수적 종속성
    • A가 B를 결정하고 B가 C를 결정하는 식으로, 한다리 걸쳐서 종속하는 경우
    • A가 B,C를 결정하고 B가 C를 결정하는 식으로 직접 종속과 이행적 종속을 동시에 만족할 수도 있음.

이행적 함수적 종속성(fd2)

 

정규화 하기

 

역정규화

  • 정규화 수준이 높아질 때 마다 테이블 분리가 일어나므로, DB 설계 자체는 중복과 갱신이상이 적어지게 되지만
  • 테이블이 분리되면서 JOIN 필요성이 늘어나니까, 성능 상의 관점에서나 쿼리 가독성의 관점에서는 좋지 않을 수 있음.
  • 그래서 요구사항에 따라 적당한 정규화 수준을 선택하는게 중요!
  • 경우에 따라서는 역정규화 해서 합쳐버리는 경우도 있다.

 

참고자료

7장_릴레이션_정규화_1.pdf
0.62MB
7장_릴레이션_정규화_2.pdf
0.49MB

 

 

테이블 설계할 때, 절대로 바뀔일이 없는 테이블인지? 를 생각해 보는 것이 중요하다.

수수료 테이블, 자주 바뀌지 않는다고 해서

결제건과 수수료ID를 조합하면 수수료율 나오니까 중복을 줄이기 위해 trade 테이블에 저장하지 않는다.” 라고 설계한 경우.

 

갑자기 x일 기준으로 수수료율을 변경해야 한다면,

"x일 이전에는 수수료율 얼마, x일 이후에는 수수료율 얼마" 라는 정보를 어딘가에 추가로 저장해야 한다.

 

따라서 바뀔 수 있는 테이블을 참조하는 경우,

  • 아예 처음 설계할 때 부터 수수료 테이블에 데이터의 유효기간(21.01~22.01)을 컬럼으로 두거나,
  • 아니면 trade 테이블에 저장할 때 수수료율도 같이 저장한다. 중복이라 생각할 수 있으나 바뀔 수 있는 정보를 저장하는 것은 중복이 아니다.

정규화 관점에서는 전자가 나을 수 있는데, 비즈니스 상황에 맞게 결정하면 된다.