본 내용은 유튜버 쉬운코드의 강의 "데이터베이스"를 참고하여 작성하였습니다.
정규화(normalization) 개념
- DB 정규화(normalization) : 데이터 중복과 insertion, update, deletion anomaly를 최소화하기 위해 일련의 normal forms(NF)에 따라 relational DB를 구성하는 과정
- Normal forms(NF) : 정규화되기 위해 준수해야 하는 몇 가지 rule들
- DB 정규화 과정 : 처음부터 순차적으로 진행하며, NF를 만족하지 못하면 만족하도록 테이블 구조를 조정한다. 앞 단계를 만족해야 다음 단계로 진행할 수 있다.
- 1NF ~ BCNF : FD와 key만으로 정의되는 NF
- 3NF까지 도달하면 정규화 됐다고 말하기도 함.
- 보통 실무에서는 3NF 혹은 BCNF까지 진행 (많이 해도 4NF)
예제에 사용될 table 스키마 소개
- 임직원의 월급 계좌를 관리하는 테이블
- 월급 계좌(bank_name)는 국민은행 / 우리은행 중 하나
- 한 임직원이 하나 이상의 월급 계좌를 등록하고 월급 비율(ratio)을 조정할 수 있음.
- 계좌마다 등급(class)이 있음.
- 국민 : STAR -> PRESTIGE -> LOYAL / 우리 : BRONZE -> SILVER -> GOLD
- 한 계좌는 하나 이상의 현금 카드와 연동할 수 있음.
table의 key & prime attribute
- super key : table에서 tuple들을 unique하게 식별할 수 있는 attributes set
- (cardinate) key : 어느 한 attribute라도 제거하면 unique하게 tuples를 식별할 수 없는 super key
- {account_id}, {bank_name, account_num}
- primary key(PK) : table에서 tuple들을 unique하게 식별하려고 선택된 (candinate) key
- {account_id}로 선택함.
- prime attribute : 임의의 key에 속하는 attribute
- account_id, bank_name, account_num
- non-prime attribute : class, ratio, empl_id, empl_name, card_id
table의 functional dependency
- {account_num} -> {나머지 특성들}
- {bank_name, account_num} -> {나머지 특성들}
- {class} -> {bank_name} : 은행마다 가지고 있는 class들이 다 달라서 class를 보면 어디 은행인지 확인할 수 있음.
- {empl_id} -> {empl_name}
1NF
- 1NF : attribute의 value는 반드시 나눠질 수 없는 단일한 값이어야 한다.
- 4행의 card_id가 값을 두 개 가지고 있어서 이를 행 두 개로 분리하고 card_id 외의 속성들을 복사함.
- 1NF는 만족하지만, 중복 데이터가 생기고 primary key도 변경해야 함. -> primary key에 card_id를 추가
- 수정된 key : {account_id, card_id}, {bank_name, account_num, card_id}
2NF
- 2NF : 모든 non-prime attribute는 모든 key에 fully functionally dependent 해야 한다.
- 모든 non-prime attribute들이 {account_id, card_id}에 partially dependent 하다.
- 모든 non-prime attribute들이 {bank_name, account_num, card_id}에 partially dependent 하다.
- PK에 card_id가 추가되었기 때문에 2NF를 위반한 것이므로 테이블에서 분리한다. -> 분리되기 전 테이블인 EMPLOYEE_ACCOUNT와 연결하기 위해 account_id도 추가함.
- EMPLOYEE_ACCOUNT 테이블이 분리되면서 중복되는 4, 5번째 행을 하나만 두고 지움.
- EMPLOYEE_ACCOUNT 테이블의 key들이 fully functionally dependent 하다.
- ACCOUNT_CARD는 PK가 {account_id, card_id}이므로 non-prime attribute가 없다.
transitive FD
- If X -> Y & Y -> Z holds, then X -> Z is transitive FD unless either Y or Z is NOT subset of any key.
- 예시 1 : {account_id} -> {empl_id} -> {empl_name}
- 예시 2 : {bank_name, account_num} -> {empl_id} -> {empl_name}
3NF
- 3NF : 모든 non-prime attribute는 어떤 key에도 transitively dependent 하면 안된다.
- non-prime attribute끼리 FD가 있으면 안된다.
- 현재는 {empl_id} -> {empl_name}가 존재함. -> 두 속성을 따로 분리함.
- 두 테이블을 연결하기 위해 EMPLOYEE_ACCOUNT 테이블에서 empl_id를 지우지 않음. (결과적으로 중복되는 데이터가 정리됨.)
BCNF
- BCNF : 모든 유효한 non-trivial FD X -> Y는 X가 super key여야 한다.
- {class} -> {bank_name} FD가 존재함. bank_name에 불필요한 중복이 많음. -> 두 속성을 따로 분리함.
- 두 테이블을 연결하기 위해 EMPLOYEE_ACCOUNT 테이블에서 class는 지우지 않음.
2NF 참고 사항
- 2NF는 key가 composite key가 아니라면 2NF는 자동적으로 만족한다?
-> 보통은 만족하지만, 예외가 있음.
- {empl_id} -> {company} 할 수 있는데, {} -> {company}도 가능하므로 company 때문에 2NF를 위반한다. -> 테이블을 분리해야 함.
denormalization
- denormalization(역정규화) : 과도한 조인(테이블을 너무 잘게 쪼개는 것)을 막기 위해 정규화 전 단계로 돌아가는 것.
- DB를 설계할 때 과도한 조인과 중복 데이터 최소화 사이에서 적정 수준을 잘 선택할 필요가 있다.
참고 사항
- 정규화 과정에서 4NF, 5NF, 6NF는 쓰이는 빈도에 비해 설명할 것이 많아서 생략했습니다.
'데이터베이스(쉬운코드)' 카테고리의 다른 글
26. B tree 1부 : 개념, 특징, 데이터 삽입 (0) | 2025.02.07 |
---|---|
25. DB 인덱스 (1) | 2025.01.30 |
22. DB 정규화의 근본 Functional dependency (0) | 2025.01.29 |
21. DB 테이블 설계를 잘못하면 생기는 문제 (0) | 2025.01.29 |
20. 요즘 concurrency control 기법 MVCC 기법 2부 : case study (1) | 2025.01.29 |