DB Normalization(정규화)

DB Normalization(정규화)

DB 정규화에 대해 알아보자


Normalization이란?


Why? 왜 정규화를 할까?

Data의 중복에 대해서는 쓸모없는 공간을 낭비 안하겠다는 생각은 이해가 간다. 중복 말고는 정규화를 하는 이유가 없을까?

바로 위에 적혀있는 anomaly 한 상황 때문이다. 데이터의 중복을 제거했어도 우리는 데이터가 저장되어 있는 데이터베이스에 읽기/쓰기/삭제 등과 같은 작업을 수행해야 할 것이다. 그 때 중복된 데이터 때문에 잘못된 수정/삭제/삽입 연산이 발생한다면 데이터베이스는 integrityconsistency 를 지켜지 못하게 될 것이다.


Data integrity and consistency

따라서 정규화가 잘 이뤄지지 않는다면 갱신 이상(anomaly)이 발생할 수 있고, data의 integrity와 consistency를 보장 못하게 만들어서 데이터베이스의 저장된 데이터에 대한 신뢰성이 떨어지게 된다.


SQL에서 정규화의 목적은 중복 데이터를 제거하고 데이터가 논리적으로 저장되도록 하는 것이다. 현재 1~6단계의 정규화 형태가 존재하지만 실제 대부분의 application에서는 제 3정규화 까지만 이뤄진다고 한다.


제 1 정규화(1NF : First Normal Form) Rules

따라서 쉽게 말하기 위해 참조한 사이트의 데이터베이스 테이블을 예시로 보도록 하자.

normalization1_1

이미지 출처

Movies Rented column을 보도록 하자. 현재 1개의 column(1개의 attribute)에 여러개의 주소가 ‘,’로 구분되어 존재하는 것을 볼 수 있다. 이는 1NF를 만족하지 못한 것이기에 다음과 같이 1개의 값으로 테이블을 아래와 같이 바꿔줘야 한다.

normalization1_2

바뀐 테이블 이미지 출처

따라서 Rule 1: 각 table의 한 칸은 1개의 값만을 가져야 한다. 를 만족할 수 있다. 그렇다면 Rule 2 는 만족을 시킨 것일까? 결론부터 말하자면 맞다. 왜냐하면 Full Names, Movies Rented 2개의 column이 composite key로써 table에 존재하는 각 tuple을 구별해주고 있다.

근데 Normalization은 데이터의 중복을 방지하는 것이라고 했으나 현재 보다시피… 이름 속성만 봐도 중복이 존재하는 것처럼 느껴진다. 2NF가 좀 더 나은 방향으로의 설계를 제시해준다.


제 2 정규화(2NF : Second Normal Form) Rules

1번째 규칙은 간단하게도 방금 본 1NF를 만족하면 되는 것 같은데 2번째 규칙이 많이 생소했다. 그래서 functional dependency에 대해서는 여기에 정리를 한 뒤에 다시 정규화에 대한 포스팅을 진행했다. 만약 functional dependency에 대해 모른다면 읽고 오는 것을 추천한다.

바로 예시를 보도록 하자.

normalization1_2

위 테이블에서는 현재 아까 1NF에서 봤던 테이블을 2NF를 지키기 위해 2개의 테이블로 나눈 결과이다. member table(1번 테이블)에는 각 row가 unique하는 것을 보장하기 위해서 membership_id 라는 attribute를 추가한 것을 볼 수 있다. 따라서 해당 테이블의 PK는 membership_id 1개이고, 그 외 모든 attribute에 대해서 partial functional dependency 가 아니기에 2NF를 만족하게 되는 것이다. Table2 같은 경우는 2개 attribute가 PK이다.


이걸로 끝난걸까?

2정규화를 했으니 이제 끝인걸까? 맨 처음의 테이블보다는 훨씬 나아졌다. 중복도 많이 없어졌고 별다른 어색함도 찾기 힘들다. 하지만 2NF에서는 다음과 같은 갱신 오류가 발생할 수 있다고 한다. 다음 예시를 보면서 어떤 문제가 발생할 수 있는지 보도록 하자.

normalization1_9

데이터 테이블 출처 : kocw

현재 위 테이블에서 PK는 학번 이다. 현재 학과전화번호학과 에 의해서 결정되는 정보이다. 근데 학과 는 PK(학번)에 의해 결정된다. 이러한 관계를 transitive functional dependency라고 하는데 2NF에서는 transitive 한 관계 때문에 다음과 같은 anomaly이 발생할 수 있다.

이러한 오류가 발생하는 이유는 2NF는 만족했더라도, 테이블 내에 transitive functional dependent 관계가 존재하기 때문이다. 이러한 관계를 제거함으로써 3NF로 넘어갈 수 있다.


제 3 정규화(3NF : Third Normal Form) Rules

이전의 2NF까지 진행된 테이블에서는 SALUTATION attribute가 FULL NAMES에 종속되고, FULL NAMES 는 PK에 종속되기에 PK와 SALUTATIONtransitive functional dependent 한 관계를 가졌어서 갱신 오류가 발생할 수 있었다.

아까 2NF의 처음에 나온 테이블을 다시 3NF에 맞게 나눠 보도록 하자.

normalization1_10

테이블을 하나 더 분해하여 transitive functional dependent 한 관계를 제거했다. 이는 더 높은 정규화 형태로 가기 위해 더 이상 분해를 못하는 상태인 테이블이 되었다.

예시로 들었던 테이블이 너무 단순했기 때문인데, 복잡한 DB에서나 다음 단계로의 정규화를 진행하기 위해 시간을 많이 쓴다고 한다. 따라서 다음 BCNF에 대해서만 알아보고 포스팅을 마무리 하겠다.


BCNF(Boyce-Codd Normal Form)

쉽게 말하면, PK가 아닌 attributes에 대해서는 determinant가 되면 안된다는 것이다. BCNF를 만족 안하는 경우에도 갱신 이상이 생길 수 있다.


공부하고 느낀점

보통 RDB 설계를 할 때에는 위와 같은 문제가 없었기에 정규화라는 개념이 생소했었다. 물론 간단한 프로젝트여서 DB 자체가 복잡한 구조를 갖지 않았기도 했었다. 하지만 JPA강의를 봤어서 그런지 프로젝트를 진행할 때, ‘당연하게 id field를 PK로’ 만들게 됐다. 결국 위와 같은 이론적 배경이 녹아있었겠지만, 실제로 저러한 엄격한 과정을 거치치 않았어도 자연스레 설계를 위와 같은 설계를 할 수 밖에 없다는 생각이 든다.



Reference

KOCW Database 9강-용환승 교수님

what is normalization?

data integrity-wiki

data consistency-wiki

1NF, 2NF, 3NF

2NF

BCNF