무작정 잘게 쪼개면 오히려 데이터를 다시 조합하기 어려워질 수 있다.
한 칸에는 하나의 값
회원의 전화번호 칸에 여러 번호를 쉼표로 묶어 넣었다고 가정해 보자.
하나만 찾고 수정하기도 어렵고, 검색 조건도 복잡해진다.
키의 일부에만 기대는 값을 분리한다
기본키가 두 속성으로 이루어진 표를 예로 들어 보자.
학생번호 → 학생이름
학생이름은 전체 기본키가 아니라 학생번호 하나만으로 결정된다.
부분 함수 종속은 복합키를 사용할 때 특히 눈에 잘 띈다. ‘학생번호와 과목번호가 함께 있어야 점수를 찾을 수 있는가?’와 ‘학생번호 하나만으로 학생이름을 찾을 수 있는가?’를 따로 물어보면 된다.
학생이름처럼 기본키의 일부만 보고 결정되는 값은 별도 학생 테이블로 분리하는 편이 자연스럽다. 이렇게 나누면 같은 학생이 여러 과목을 수강하더라도 이름을 반복 저장할 필요가 줄어든다.
키가 아닌 값이 다른 값을 결정하면 분리한다
예약번호가 회원번호를 결정하고, 회원번호가 회원이름을 결정한다고 하자.
회원이름은 기본키인 예약번호에 직접 의존하는 것이 아니라 회원번호를 거쳐 결정된다.
결정자가 후보키가 되도록
정규화를 한 단계 더 엄격하게 바라보는 기준도 있다.
어떤 속성이 다른 속성을 결정한다면, 그 결정자가 후보키여야 한다는 기준이다.
정규화가 항상 많을수록 좋은 것은 아니다
표를 나누면 중복은 줄어들지만 데이터를 조회할 때 여러 표를 다시 연결해야 한다.
조회 속도가 매우 중요한 시스템에서는 일부 중복을 허용해 성능을 높이기도 한다.
반정규화는 처음부터 중복을 허용하자는 뜻이 아니다. 먼저 데이터의 정확성과 일관성을 확보한 뒤, 실제 성능 문제를 확인하고 필요한 부분만 의도적으로 합치는 선택에 가깝다. 구조 변경에는 언제나 얻는 것과 잃는 것이 함께 있다.