본문 바로가기
DataBase/개념

잘못 설계된 데이터베이스는 어떻게 수정해야 할까? (1) (feat.이상현상)

by 깐니 2020. 7. 28.

목차
1. 이상현상
2. 함수 종속성
3. 정규화

들어가기 전..

데이터베이스에 저장된 데이터는 일관성과 정확성을 가져야한다.


데이터베이스 설계를 하면 테이블이 생성된다.
하지만 잘못된 설계를 하면 테이블에 삽입,삭제,수정 작업을 했을 시, 이상현상이 나타난다.
이상현상은 데이터베이스가 가져야 하는 일관성을 훼손하게 되고, 데이터의 무결성을 깨뜨리게 된다.

이상현상이 일어난, 잘못 설계된 데이터베이스를 수정하여 정상으로 만드는 과정을 정규화라고 한다.

이번 포스팅에서는 이상현상에 대해 알아보자.

1.
이상현상이란 ?

데이터베이스의 설계가 잘못되었을 때 발생하는 문제이다.
그렇다면 어떤 이상현상이 있을까?

예시를 들어 생각해보자. 
다음은 계절학기 데이터베이스 (Summer)이다. 

sid (학번) class (과목명) price (가격)
100 Python 10000
150 C 15000
200 Python 10000
250 JavaScript 20000


(1) 삭제이상

200번 학생이 수강신청을 취소하였다.고 하였을 때 다음과 같은 쿼리문 작성해서 튜플을 삭제해보자
-> DELETE FROM Summer WHERE sid=200;
이후, 다른 학생이 수강신청을 하기 위해 Python 강좌의 가격을 검색하고자한다.
-> SELECT price "Python 수강료" FROM Summer WHERE class="Python";

하지만 해당강좌의 수강료를 알 수 없다.
왜냐하면 200번학생의 수강정보를 삭제하였을 때 Python강좌의 정보도 함께 삭제 되었기 때문이다.

이러한 현상을 연쇄삭제 문제 (triggered delection)라고 한다.
즉, 삭제이상이란 투플 삭제 시 같이 저장된 다른 정보까지 연쇄적으로 삭제되는 현상이다.

 

(2) 삽입이상

Kotlin 강좌가 새로 개설되었다. 수강료는 25000원이고, 아직 신청한 학생이 없다.
Kotlin 강좌 정보를 계절학기 테이블에 삽입해보자.
-> INSERT INTO Summer VALUES (NULL, 'Kotlin', 25000);
위 쿼리와 같이, NULL값을 입력해야하는 경우가 발생하였다. 이것이 왜 문제인지 알아보자.

sid(학번) class(과목명) price(가격)
100 Python 10000
150 C 15000
200 Python 10000
250 JavaScript 20000
NULL Kotlin 25000

현재 테이블은 위와 같이 수강학생은 총 4명임을 알 수 있다.
수강학생을 알기위해 집계함수를 사용한 쿼리를 작성해보자.
-> SELECT COUNT(*) "수강인원" FROM Summer;
수강학생은 총 4명이지만, 위 쿼리의 결과는 5가 나오게 된다.

즉, 삽입이상은 투플삽입 시 특정 속성에 해당하는 값이 없을 경우, NULL값을 입력해야 하는 문제다.

 

(3) 수정이상

Python강좌가 10000원에서 1000원으로 변경되었다.
-> UPDATE Summer SET price=1000 WHERE class='Python'AND sid=100;
이후 데이터베이스를 전체 조회해보자.
-> SELECT * FROM Summer;

sid(학번) class(과목명) price(가격)
100 Python 1000
150 C 15000
200 Python 10000
250 JavaScript 20000


Python강좌의 수강을 어떤 학생은 1000원에, 어떤 학생은 10000원에 듣게 되는 문제가 발생하였다는 것을 알 수 있다.
즉, 수정이상이란 투플 수정 시 중복된 데이터의 일부만 수정되어 데이터의 불일치 문제가 일어나는 현상이다.

 

 

그렇다면, 이러한 현상을 어떻게 수정해야할까?

먼저 결과부터 말하자면, 수정된 테이블은 다음과 같다.

Summer(sid, class, price)

sid(학번) class(과목명) price(가격)
100 Python 10000
150 C 15000
200 Python 10000
250  JavaScript 20000


SummerPrice (class, price)

class(과목명) price(가격)
Python 10000
C 15000
JavaScript 20000


SummerEnroll (sid, class)

sid(학번) class(과목명)
100 Python
150 C
200 Python
250 JavaScript


Summer 테이블을 SummerPrice테이블과 SummerEnroll테이블로 분리하였다.
학생들의 수강신청 정보와 수강료 정보를 따로 저장한 것이다.

이것에 대해 다음 포스팅에서 알아보도록 하자. 😉

 

 

Reference
📕데이터베이스 이론과 실습