본문 바로가기
개발/DBMS

RDBMS 정규화(Normalization) - 2/2

by EPdev 2020. 9. 27.
728x90

지난 글에서 RDBMS 정규화가 왜 필요한지 이상현상(Anomaly)과 함께 설명하였다. 정규화가 6단계로 이뤄져있다는 것도 간략히 알아봤다.

그럼 이제 정규화에 대해서 본격적으로 알아보겠다.

* 참, 정규화는 단계가 점점 높아지는데 상위 단계의 정규화는 하위 단계의 정규화를 만족하고 있다는 것을 알아야한다.

 

1. 1차 정규화(1NF) - 원자값으로 구성

1차 정규화 - 원자값으로 구성

위 Tables을 보자.

첫 번째 table에는 한 user에게 email 주소가 두 개 들어가 있다. 이게 원자값으로 구성되지 않다고 볼 수 있다.

여기서 문제는 가령 유저가 하나의 email 주소를 변경했을 때, 기존 email에 값에서 변경된 값을 찾아서 다시 넣어줘야한다거나 다 가져와서 변경된 걸 찾아넣고 모두 덮어쓰기를 한다거나의 문제가 있을 수 있다. (행여 중복값이 들어갈 수도 있다.)

예전에, 게시글에 여러 사진이 들어가는 기능을 만들 때 위처럼 pictures column을 하나 두고 하나의 글에 모든 사진을 넣었던 기억이 난다. 관리하기 어려워서 JSON형식으로 pictures를 넣어줬었는데, 전체 사진 중 몇 개를 수정/삭제할 때 해당 사진을 찾아서 수정/삭제했던 적이 있다. 이제보니 참 어리석은 짓이었던 것 같다.

 

어쨌든! 이를 아래 table처럼 나눠줘야 email을 원자값으로 구성하였다고 볼 수 있으며, 1차 정규화를 만족하는 것이다.


2. 2차 정규화(2NF) - 부분함수 종속 제거

위의 tables을 보자.

UserName과 Sports가 Term과 연관이 있다. UserName은 여러 개 있을수도 있고, Sports도 여러개 있을 수 있으니 둘이 묶어야 Term이 정해진다.

그리고 Sports가 Prices랑 연관이 있다. 여기서 UserName, Sports - Term | Sports - Prices 를 보면 Sports가 부분적으로 관계가 있다. 이를 부분함수 종속 관계라고 한다. 아래 그림을 보면 좀더 이해가 쉽다.

어쨌든, 부분적으로 연관되어 있는 두 값을 나누라는게 2차 정규화이다. 부분함수 관계를 끊어야한다. 그래서 위의 Tables 중 두 번째 table을 보면 이게 2차 정규화가 된 table이다.


3. 3차 정규화(3NF) - 이행함수 종속 제거

3차 정규화 - 이행함수 종속 제거

위 table을 보면 SnackNo이 Brand와 연관이 있고 Brand가 Address로 연관되어 있다. 그러니까 A -> B, B -> C로 A -> C가 되는 관계를 이행함수 관계라고 한다. 아래는 위 table의 관계를 그림으로 나타낸 것이다.

여기서 발생할 수 있는 문제는 뭘까?

Snack의 생산 Brand가 바뀌는 경우가 있다면, 해당 Address도 바꿔줘야하는 갱신 이상이 발생할 수 있다고 본다.

그러니까 이를 또 쪼개줘야 3차 정규화를 만족시킨다고 할 수 있다.


4. 보이스-코드 정규화(BCNF : Boyce-Codd NF) - 결정자 함수이면서 후보키가 아닌 것 제거

보이스-코드 정규화 - 결정자 함수이면서 후보키가 아닌 것 제거

보이스-코드 정규화는 3차 정규화와도 매우 비슷해서, 3.5차 정규화라고도 불린다고 한다. 사실 아직도 3차 정규화와 보이스-코드 정규화의 차이를 뚜렷히 구분하지 못 하겠다. 어쨌든 그 정의는 다르니 한번 살펴보자.

 

Table을 위와 같이 작성하였고 학생번호와 과목을 하나의 기본키로 본다면, 여기선 이를 통해 선생님을 식별할 수 있다.

그런데 선생님은 과목과 연관이 되어 있다. 한 선생님이 갑자기 수학과 과학을 다 가르치긴 쉽지 않으니 말이다.

선생님이 과목을 대표하고 선생님을 통해 과목을 결정할 수 있으니 선생님을 결정자라고 할 수 있다.

 

하지만, 선생님은 테이블에서 중복될 수 있다. 결정자이지만 중복이 가능하다는 것은 키로써 역할을 못 한다는 것이다. 즉, 다시 말해 후보키가 될 수 없다는 것이다. (후보키에 대해서는 따로 공부해보자.)

이 관계도는 아래와 같다.

여기서 발생할 수 있는 문제는 뭘까?

가령, 영어를 가르치는 새로운 선생님이 들어왔다고 가정하자. 그럼 row를 추가해줘야하는데, 당장 해당 과목을 듣는 학생이 없다. null이라는 것이다. 그런데 우리가 처음에 학생과 과목을 통해 기본키를 설정했다. 기본키에 null이 들어갈 수 없으니 문제가 발생한다.

어찌됐든, 이를 아래 테이블이나 그림처럼 나눠줘야 이상현상을 막을 수 있겠다는 것이다.

 

  • 보통은 BCNF 까지 진행을 했다면, 이후 정규화에 대해선 만족을 한다고 한다. 그러니 여기까지만 진행해도 Table에 큰 문제는 없을 것이라는 것이다. 하지만 무엇인지 알고 있는거랑 모르고 있는 거는 차이가 있으니 계속 봐보자.

5. 4차 정규화(4NF) - 다치(다중값) 종속 제거

4차 정규화 - 다치(다중값) 종속 제거

자 이젠 4차 정규화이다. 다치(다중값) 라는 개념부터 알아야겠다. 다치(다중값)이란 말 그대로 값이 여러개라는 뜻이다. 첫번째 테이블을 보면 개발자는 많은 자격증을 가질 수도 있고, 많은 언어를 구사할 수도 있다. 그런데 이 자격증과 언어를 합쳐서 놓는다면, 앞서 배운 이상현상이 발생할 수 있다.

가령, 개발자가 새로운 자격증을 땄다고 해서 row를 추가하려면, 언어 column에도 어떠한 값이든 추가해줘야한다. 또는 개발자의 자격증이 만료돼서 삭제한다고 하면, 그 개발자의 언어도 삭제된다. data 관리가 제대로 되지 않는 느낌이다.

 

그래서 개발자를 기준으로 중복된 값을 허용할 수 있게 나눠줘야 4차 정규화를 만족시켰다고 할 수 있다.

 

아래는 위 tables의 관계도이다. 한번 참고만 하자.


6. 5차 정규화(5NF) - 조인 종속성 제거

5차 정규화는 사실 나도 잘 이해가 안 간다. 하지만 조인 종속성이 무엇인지, 어떠한 문제가 있고 어떻게 해결하는지 등을 통해 대략적으로 알아보겠다.

 

먼저 조인 종속성이란 무엇일까?

4차 정규화가 된 어떠한 테이블들을 Join 연산을 시켰을 때, 정규화 이전의 table과 값이 달라지는 경우를 조인 종속성을 가졌다고 말한다. 조인 또는 정규화 과정에서 data가 손실되어 결과가 달라지는 것이다.

아래 테이블을 보자. 조인을 했더니 이상한 테이블이 나왔다.

4차 정규화 테이블을 조인 연산한 결과

이를 정상적으로 나타내기 위해 아래처럼 모든 속성 관계에 대한 테이블을 만들어서 조인했을 때 원래의 데이터가 나올 수 있게 한다.

5차 정규화 - 조인 종속성 제거

관계도는 아래와 같다.

 


여기까지 해서, RDBMS의 정규화에 대해서 알아보았다.

중간에 잠깐 언급했듯이, 보통은 3차 정규화까지 만족을 하면 그 뒤에 정규화들은 크게 문제가 없다고 한다.

 

나도 처음에 아무 것도 모르고 Table 구조를 짜거나 관계를 맺어서 고생했던 적이 많다.

그래서 Table을 어떻게 설계하는냐는 정말 중요한 내용이라고 생각한다.

 

그런데 주의해야할 점은, 정규화는 Data의 무결성 보장해주거나 이상현상 등을 막아준다고 하지만

무조건적인 정규화는 수많은 조인으로 인한 성능저하을 야기할 수 있다고 한다.

 

그래서 역정규화 / 반정규화에 대한 개념도 나온다.

이 또한 하나의 개념이니 깊게 들어가면 얘기가 길어질 듯 하니 기회가 되면 다른 글에서 작성해보겠다.

여기서 간단히 보자면, 정규화가 너무 되어서 성능이 저하되는 테이블에 대해서는 정규화를 다소 만족하지 않는다고 해도 용인해주겠다. (성능을 위해서) 뭐 이렇게 간단히 생각하면 된다.

 

728x90

'개발 > DBMS' 카테고리의 다른 글

JOIN 문제 해결  (0) 2020.11.11
문자+숫자 DB 컬럼 정렬하기  (0) 2020.11.09
JOIN 문제  (0) 2020.11.05
RDBMS 정규화(Normalization) - 1/2  (2) 2020.09.24
Stored Procedure - 저장 프로시저  (0) 2020.08.11

댓글