[데이터베이스] 정규화? 비정규화? (Normalization & De-normalization)
정규화
- 이상현상이 있는 릴레이션을 분해하여 이상현상을 없애는 과정
- 테이블 간에 중복되는 데이터를 허용하지 않는다는 것
- 중복된 데이터를 허용하지 않음으로써 무결성을 유지할 수 있다
릴레이션 : 관계형 데이터베이스에서 정보를 구분하여 저장하는 기본 단위이다. 결국, 릴레이션은 DB 테이블이다.
무결성 : 데이터의 정확성, 일관성, 유효성이 유지 되는 것을 의미
이상현상 : 테이블을 설계할때 잘못 설계하여 데이터를 삽입, 삭제, 수정할 때 논리적으로 생기는 오류 (삽입 이상, 갱신 이상, 삭제 이상)
장점
- 데이터베이스 변경 할때 이상현상을 제거 할 수 있음
- 정규화된 데이터베이스에서는 새로운 데이터 형의 추가로 인한 확장 시 그 구조를 변경하지 않아도 되거나 일부만 변경해도 된다
단점
- 릴레이션을 나눔으로써 릴레이션 간의 Join 연산이 많아진다
- 질의에 대한 응답 시간이 느려질수 있다
- Join 연산이 많이 발생하여 성능 저하가 나타나면 반정규화를 적용 할 수 있다
제 1 정규화 (1NF)
- 테이블의 컬럼이 원자값을 갖도록 테이블을 분해하는 것
규칙
- 각 컬럼이 하나의 속성만을 가져야함
- 하나의 컬럼은 같은 종류나 타입의 값을 가져야한다
- 각 컬럼이 유일한 이름을 가져야함
- 칼럼의 순서가 상관없어야 함
제 1 정규화 적용전
수강과목ID | 수강과목 | 수강자 |
1 | ai | 홍길동 |
2 | java | 이순신, 홍길동 |
3 | c | 유관순 |
- Java과목은 이순신, 홍길동 여러 수강자를 갖고 있어 제 1정규화를 만족하지 못한다
제 1 정규화 적용후
수강과목ID | 수강과목 | 수강자 |
1 | ai | 홍길동 |
2 | java | 이순신 |
3 | c | 유관순 |
2 | java | 홍길동 |
원자값 : 속성값이 더 이상 논리적으로 분해될 수 없는 값
제 2 정규화(2NF)
- 제 1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것
- 완전 함수 종속 : 기본키의 부분집합이 결정자가 되어선 안된다는 것
규칙
- 제 1 정규화를 만족
- 모든 컬럼이 부분적 종속이 없어야 함
- 모든 컬럼이 완전 함수 종속을 만족해야 함
제 2 정규화 적용전
회원ID | 회원이름 | 회원주소 | 상품코드 | 상품명 | 가격 |
101 | 홍길동 | 서울시 | S100 | 소파 | 200 |
102 | 이순신 | 부산시 | B100 | 침대 | 300 |
103 | 유관순 | 대전시 | S100 | 소파 | 200 |
101 | 홍길동 | 서울시 | S100 | 의자 | 150 |
- 회원이름과 회원 주소는 회원 ID에 종속되어 있고 상품명과 가격은 상품코드에 종속 되어 있다
- 한 테이블에서 회원 정보, 상품 정보, 구매 내역이 모두 포함되어 있어 데이터 중복이 발생하고 무결성이 유지되지 않는다
제 2 정규화 적용후
회원ID | 회원이름 | 회원주소 |
101 | 홍길동 | 서울시 |
102 | 이순신 | 부산시 |
103 | 유관순 | 대전시 |
상품코드 | 상품명 | 가격 |
S100 | 소파 | 200 |
B100 | 침대 | 300 |
S100 | 의자 | 150 |
회원ID | 상품코드 |
101 | S100 |
102 | B100 |
103 | S100 |
101 | S100 |
제 3 정규화(3NF)
- 제 2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것
- 이행적 종속 : a -> b, b -> c 일때 a -> c 가 성립이 된다는 것
규칙
- 제 2 정규화를 만족
- 기본키를 제외한 속성들 간의 이행 종속성이 없어야한다
제 3 정규화 적용 전
학생ID | 학생이름 | 강의ID | 강의명 | 교수ID | 교수이름 |
S001 | 김영희 | L001 | 수학 | P001 | 이은택 |
S001 | 김영희 | L002 | 영어 | P002 | 김진희 |
S002 | 이철수 | L001 | 수학 | P001 | 이은택 |
S003 | 최민수 | L003 | 과학 | P003 | 박현정 |
- 이행적 함수 종속이 발생
- 학생이름은 학생ID에 종속, 강의명은 강의ID에 종속, 교수이름은 교수 ID에 종속
- 강의ID를 통해 교수 ID와 교수이름 정보에도 간접적으로 종속되어 있음
- 이행적 함수 종속 관계 : 강의 ID -> 교수 ID -> 교수이름
- 이런 이행적 종속성 때문에 중복 데이터와 데이터 무결성 문제가 발생할 수 있음
제 3 정규화 적용 후
학생ID | 학생이름 |
S001 | 김영희 |
S002 | 이철수 |
S003 | 최민수 |
강의ID | 강의명 | 교수ID |
L001 | 수학 | P001 |
L002 | 영어 | P002 |
L003 | 과학 | P003 |
교수ID | 교수이름 |
P001 | 이은택 |
P002 | 김진희 |
P003 | 박현정 |
학생ID | 강의ID |
S001 | L001 |
S001 | L002 |
S002 | L001 |
S003 | L003 |
BCNF (Boyce-codd Normal Form)
- 3차 정규화를 조금 더 강화한 버전
- 3차 정규화에서 해결할 수 없었던 이상현상을 해결
- 3차 정규화를 만족하면서 모든 결정자가 후보키 집합에 속한 정규형
규칙
- 제 3 정규화를 만족
- 모든 결정자가 후보키 집합에 속해야 함
비정규화
- 하나 이상 테이블에 데이터를 중복해 배치하는 최적화 기법 -> 의도적으로 정규화 원칙을 위배한다
- 데이터 중복이나 그로 인해 발생하는 데이터 갱신 비용은 감수하는 대신 조인 횟수를 줄여 효율적인 쿼리를 날릴 수 있다
언제 사용할까?
- 디스크 I/O 량이 많아서 조회 시 성능이 저하될 때.
- 테이블끼리의 경로가 너무 멀어 조인으로 인한 성능 저하가 예상될 때
- 칼럼을 계산하여 조회할 때 성능이 저하될 것이 예상될 때
대상
- 테이블에 대량 데이터가 있고 대량의 범위를 자주 처리하는 경우, 성능 상 이슈가 있을 경우
- 테이블에 지나치게 조인을 많이 사용하게 되어 데이터를 조회하는 것이 기술적으로 어려울 경우
- 자주 사용되는 테이블에 액세스하는 프로세스의 수가 가장 많고 항상 일정한 범위만을 조회
장점
- 빠른 데이터 조회 -> 따로 join을 하지 않아도 됨
- 조회 쿼리가 간단해짐 -> 버그 발생 가능성도 낮음
단점
- 데이터 갱신이나 삽입이 비용이 높고, 코드가 작성하기 어려움
- 데이터간의 일관성 유지가 어려움
- 중복하여 저장하므로 더 많은 저장공간을 차지
출처 : https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/main/Database#part-1-5-database
Interview_Question_for_Beginner/Database at main · JaeYeopHan/Interview_Question_for_Beginner
:boy: :girl: Technical-Interview guidelines written for those who started studying programming. I wish you all the best. :space_invader: - JaeYeopHan/Interview_Question_for_Beginner
github.com