(DB) 정규화

HEYDAY7·2022년 12월 23일
0

서버 관련 Background

목록 보기
10/10

DB 정규화

정규화란 릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스 이상 현상이 일어나 이를 해결하거나, 저장 공간을 효율적으로 사용하기 위해 릴레이션을 여러 개로 분리 하는 과정이다. 여기서 기억해둘 핵심은 "저장 공간"을 효율적으로 사용하기 위함이라는 것이다.

정규화 단계

단계라는 키워드를 사용하는 것이 적합한지는 모르겠으나, 이 정규화도 여러 종류가 존재한다. 일반적인것으론 1NF~6NF와 BCNF 가 있으나, 실제적으로는 1NF~3NF 정도까지의 과정을 거친다고 한다.(여기서 NF는 Normal Form의 준말이다.)

제 1 정규화, 1NF

1 정규형의 특징은, 원자성이다. 테이블의 컬럼 값이 원자값, 즉 하나의 값을 갖도록 테이블을 분해하는 것이다. 쉽게 말해 특정 테이블에서 임의의 데이터가 "과일" 이라는 컬럼에 대해 ["사과", "배"] 라는 값을 가지고 있다면, 이는 원자값이 아닌 것이다. 이 경우 이를 두개의 데이터로 나누는 것을 제 1 정규화라고 한다.

제 2 정규화, 2NF

제 1 정규화를 진행한 테이블에 대해, 완전 함수 종속을 만족하도록 하는 것이다. 여기서 완전 함수 종속은 기본키의 부분집합이 특정 필드의 결정자가 되면 안된다는 뜻이다. 사실 말로는 나도 잘 와닿지 않는다. 다음과 같은 예시가 있다.

제 3 정규화, 3NF

제 2 정규화를 진행한 테이블에서 이행적 종속을 없애는 것을 말한다. 이행적 종속이란 A->B와 B->C가 존재하는 상황에서, 논리적으로는 A->C가 성립하는데 이러한 종속을 테이블에서 제거하는 것을 말한다.

이 정규화를 하는 이유는 다음과 같다. 만약 기존 테이블에서 두번째 데이터의 과일을 배 -> 사과 로 변경하고 싶다고 하자. 물론 데이터의 변경 자체는 말 그대로 배 자체를 사과로 바꾸기만 하면 된다. 하지만 이 경우 가격이 600인 사과가 존재해야 한다는 만일의 가정 또한 필요해진다. 그게 아닌 경우라면 두번째 데이터의 가격 역시 600 -> 500으로 바뀌어야 할 것이다. 제 3 정규형은 이러한 일이 일어나는 것을 피하기 위해 이행적 종속을 없앤 것이다. 제 3 정규화를 거친 오른쪽을 보면 B의 과일을 사과로 바꾸더라도, 사과 -> 500이라는 가격 매핑은 그대로 유지되게 된다.

보이스 코드 정규형, BCNF

제 3 정규화를 진행한 테이블에서, 모든 결정자가 후보키인 상태로 만드는 것을 말한다. 여기서 결정자는 어떠한 칼럼 Y가 X에 대해서 결정될 때, 즉 X->Y 관계가 성립될 때 X를 결정자라고 한다. 즉 특정한 결정자가 후보키가 되지 못한다면, 후보키가 될 수 있는 범주로 테이블을 자르는 것이다.

정규화의 이면

이 정규화라는 것은 처음에 언급했듯이 "저장 공간"을 효율적으로 사용하기 위해 진행하는 과정이다. 그렇기에 DB 정규화가 DB의 처리속도의 향상을 항상 가져올 것이라는 것은 틀린 말이 된다.
여기서 DB의 처리속도란 CRUD에서 R과 CUD로 구분지을 수 있다. 데이터를 입력하고 수정하고 삭제하는 처리속도의 경우, 정규화를 수행하면 속도가 빨라진다. 실제적으로 한 테이블의 용량도 최소화되기에 그러할 것이다. 그러나 오히려 Read, 즉 조회 성능의 경우 조건에 따라 처리 속도가 저하될 수 도 있다. 그러한 이유야 여러가지가 있을 수 있지만 join의 영향도 꽤나 있을 것이다. 정규화를 하다보면 table을 여러개로 나누게 된다. 그렇다 보니 특정 쿼리의 경우 table join을 여러 번 해야할 수 있기 때문일 것이다.

확정적으로 말할 수 있는 것은 아니나, 결국 기억해야 하는 것은 정규화, 반정규화(비정규화, 역정규화라고도함. DB 성능 향상을 위해 데이터 중복을 허락해 데이터를 묶는 행위들의 일종)가 무조건적인 성능 향상 및 하락을 가져오는 것은 아니며, 상황에 맞게 적당한 수준으로 적용해야 한다는 것이다.

아래 링크에서 좀 더 자세한 예시들을 살펴볼 수 있다.
https://dataonair.or.kr/db-tech-reference/d-guide/sql/?pageid=5&mod=document&uid=332

profile
(전) Junior Android Developer (현) Backend 이직 준비생

0개의 댓글