이 글은 데이터베이스 스터디 중 학습한 내용을 정리한 것입니다.
1. 이상현상
이상 현상이란?
데이터베이스를 잘못 설계하면 불필요한 데이터 중복이 발생하여 릴레이션에 대한 데이터의 삽입,수정,삭제 연산을 수행할 때 부작용들이 발생할 수 있다. 이러한 부작용을 이상 현상이라고 한다. 이상 현상을 제거해가면서 데이터베이스를 올바르게 설계해 나가는 과정이 정규화이다.
삽입 이상
새 데이터를 삽입하기 위해 불필요한 데이터도 함께 삽입해야 하는 문제
위 테이블에서 (고객아이디, 이벤트번호)가 기본키이기 때문에, melon이라는 고객의 데이터를 위 테이블에 삽입하려면, 반드시 이벤트번호가 있어야 한다. 따라서, 이벤트 등록이 되지 않은 고객은 위 테이블에 삽입될 수 없다.
갱신 이상
중복 튜플 중 일부만 변경하여 데이터가 불일치하게 되는 모순의 문제
위 테이블에서, 한 명의 고객은 여러 이벤트에 등록될 수 있다. 이에 따라, 고객에 대한 정보도 함께 가지고 있어, 고객이름, 등급이 중복되게 된다. 그런데 만약, apple이라는 아이디를 갖는 고객의 등급을 바꿨는데, 다른 이벤트번호를 갖고있는 튜플들의 등급을 함께 수정해주지 않는다면, 중복 튜플 같에 데이터가 불일치하게 된다.
삭제 이상
튜플을 삭제하면 꼭 필요한 데이터까지 함께 삭제되는 데이터 손실의 문제
orange라는 아이디를 가진 고객이 이벤트를 취소했다고 가정하자. 이벤트 취소를 위해 위 테이블에서 해당 튜플(고객아이디 == orange, 이벤트번호 == E004)은 삭제되어야 한다. 그런데, 해당 튜플을 삭제하게 되면, 이벤트 정보 뿐만 아니라, 고객에 대한 정보가 함께 삭제되게 된다. 이처럼 연쇄 삭제 현상이 발생하는 문제를 ‘삭제 이상’이라고 말한다.
2. 함수적 종속
함수 종속성이란?
하나의 릴레이션을 구성하는 속성들의 부분 집합을 X와 Y라 할 때, 어느 시점에서든 릴레이션 내의 모든 튜플을 대상으로 한 X 값에 대한 Y 값이 항상 하나면 “X가 Y를 함수적으로 결정한다” 또는 “Y가 X에 함수적으로 종속되어 있다”라고 표현한다. 함수 종속 관계는 X → Y로 표현하고, X는 결정자, Y는 종속자라고 한다.
위와 같은 테이블이 있을 때, ‘고객아이디’에 의해 (‘고객이름’ , ‘등급’) 이 결정된다.
이를 고객아이디 → ( 고객이름 , 등급 )으로 표현한다. 고객아이디는 튜플들을 구분하는 유일한 값이기 때문에, 동일한 고객아이디에서 다른 ( 고객이름 , 등급 ) 이 존재할 수는 없다.
위 릴레이션이 갖고 있는 함수 종속 관계는 아래와 같다.
- 고객아이디 → 고객이름
- (고객아이디, 이벤트번호) → 당첨여부
- (고객아이디, 이벤트번호) → 고객이름
고객이름 속성의 경우 (고객아이디, 이벤트번호)에 종속되어 있으며, 결정자의 부분집합인 (고객아이디)에도 종속되어 있다. 이런 경우는 고객이름 속성이 (고객아이디, 이벤트번호) 속성 집합에 부분 함수 종속되었다고 말한다. 반면, 당첨여부 속성은 (고객아이디, 이벤트번호)의 일부분이 아닌 전체 속성 집합에 종속되엉 있는데, 이 경우 당첨여부 속성이 (고객아이디, 이벤트번호) 속성 집합에 완전 함수 종속되었다고 말한다.
완전 함수적 종속이란?
완전 함수 종속(FFD;Full Functional Dependency)은 릴레이션에서 속성 집합 Y가 속성 집합 X에 함수적으로 종속되어 있지만, 속성 집합 X의 전체가 아닌 일부분에는 종속되지 않음을 의미한다.
부분 함수적 종속이란?
부분 함수 종속(PFD;Partial Functional Dependency)은 속성 집합 Y가 속성 집합 X의 전체가 아닌 일부분에도 함수적으로 종속됨을 의미하므로, 부분 함수 종속 관계가 성립하려면 결정자가 여러 개의 속성들로 구성되어 있어야 한다.
이행적 함수적 종속이란?
A→B 이고 B→C일 때, A→C를 만족하는 관계를 말한다. 예를 들면, 사람은 유일한 (몸무게 , 키)를 갖으며, (몸무게, 키) 는 BMI 지수를 결정한다.
사람ID | 몸무게 | 키 | BMI 지수(몸무게/키^2) |
100 | 50 | 150 | 22 |
200 | 80 | 176 | 26 |
즉, 사람ID → ( 몸무게, 키 ) 이고, ( 몸무게 , 키 ) → BMI 지수 이므로, 사람ID → BMI 지수이게 된다.
3. 정규화, 반정규화
정규화란?
정규화란, 함수 종속성을 이용하여 릴레이션을 연관성이 있는 속성들로만 구성되도록 분해해서, 이상 현상이 발생하지 않는 올바른 릴레이션으로 만들어 나가는 과정을 말한다. 정규화의 목표는 관련이 없는 함수 종속성은 별개의 릴레이션으로 표현하는 것이다.
릴레이션의 특성을 고려해서 적합한 정규형을 선택해야 한다. 일반적으로는 기본 정규형에 속하도록 릴레이션을 정규화하는 경우가 대부분이므로, 기본 정규형의 제약조건은 정확히 파악해둘 필요가 있다.
제 1 정규형
💡 릴레이션에 속한 모든 속성의 도메인이 원자 값(atomic value)으로만 구성되어 있으면 제1 정규형에 속한다.
위 테이블에서 ( 이벤트번호 , 당첨여부) 가 atomic하지 않다. 이는 관계형 데이터베이스의 특성인, “속성의 원자성”에 위반된다. 이렇게 데이터가 원자성을 갖고 있지 않을 경우, 데이터 처리를 위해 속성 값을 분리하는 작업이 요구되며, 만약 특정 이벤트번호에 해당하는 튜플을 찾고자 할 때, 위 컬럼에서 각각의 이벤트번호를 분리하는 처리를 진행해야 될 것이다. 이 경우 인덱스를 활용할 수 없으므로, 관계형 데이터 베이스의 장점을 누리지 못하게 된다.
원자값을 갖도록 분리하여, 제 1 정규형을 만족하도록 변경한 테이블은 아래와 같다.
그러나, 아직 ‘삽입 이상’ , ‘갱신 이상’ , ‘삭제 이상’ 이 존재한다.
제 2 정규형
💡 릴레이션이 제 1 정규형에 속하고, 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속되면 제 2 정규형에 속한다.
위 테이블들은 제 2 정규형에 맞춰 분리하였지만, 아직 고객 릴레이션에는 이상 현상이 발생할 수 있다.
제 3 정규형
💡 릴레이션이 제 2 정규형에 속하고, 기본키가 아닌 모든 속성이 기본키에 이행적 함수 종속이 되지 않으면 제 3 정규형에 속한다.
제 2 정규형에서 도출된 고객 릴레이션은 아래의 이행적 함수 종속이 존재한다.
관계를 보자면, 고객아이디 → 등급 이고, 등급 → 할인율 이여서, 고객아이디 → 할인율 의 논리적 관계가 형성된다. (고객 → 등급) 과 (등급 → 할인율) 의 관계를 각각 릴레이션으로 분리하여 제 3 정규형을 만족할 수 있다.
BCNF 정규형
💡 릴레이션의 함수 종속 관계에서 모든 결정자가 후보키이면 보이스/코드 정규형에 속한다.
위와 같은 테이블이 있다고 가정하자. 고객은 여러 인터넷 강좌를 신청할 수 있지만, 동일한 인터넷 강좌를 중복해서 신청할 수는 없다. 인터넷 강좌를 담당하는 강사는 여러명일 수 있지만, 한명의 강사는 하나의 인터넷 강좌만 담당한다.
따라서, 후보키는 (고객아이디 , 인터넷강좌) , (인터넷강좌 , 당당강사번호)로 도출되며, 기본키로는 (고객아이디 , 인터넷강좌)를 선택했다고 가정하자. 제 3 정규형을 만족하지만, 아래와 같이 이상현상이 발생할 수 있다.
위 테이블에서 속성을 기준으로 관계를 매핑하면, 고객아이디(1) - 인터넷강좌(M) 관계를 갖고, 인터넷강좌(1) - 담당강사번호(M) 관계를 갖는다. 후보키가 아닌 ( 담당강사번호 )를 분리함으로써 이상현상을 방지할 수 있다.
반정규화
반정규화란, 정규화된 엔터티, 속성, 관계에 대해 시스템의 성능향상과 개발(Development)과 운영(Maintenance)의 단순화를 위해 중복, 통합, 분리 등을 수행하는 데이터 모델링의 기법을 의미한다.
데이터 무결성이 깨질 수 있는 위험을 무릅쓰고 데이터를 중복하여 반정규화를 적용하는 이유는 데이터를 조회할 때 디스크 I/O량이 많아서 성능이 저하되거나 경로가 너무 멀어 조인으로 인한 성능저하가 예상되거나 칼럼을 계산하여 읽을 때 성능이 저하될 것이 예상되는 경우 반정규화를 수행하게 된다.
참고자료
'CS > 데이터베이스' 카테고리의 다른 글
[DB] Real MySQL 8.0 - 8. 인덱스 & B-tree (1) | 2024.01.23 |
---|---|
[DB] SQL - JOIN (1) | 2024.01.23 |
[DB] Real MySQL 8.0 - 4.2 InnoDB 스토리지 엔진 아키텍처 (2) | 2024.01.22 |
[DB] SQL 질문 정리 (0) | 2024.01.18 |
[DB] SELECT 문장 처리 순서 (2) | 2024.01.18 |