데이터 모델링 - 정규화(Normalization)

KDG: First things first!·2024년 8월 21일
0

DB

목록 보기
6/7


정규화(Normalization)

정규화: 정규화란 데이터베이스 설계에서 데이터간의 중복을 제거하여 데이터의 무결성(Intergrity)을 유지하고 저장 공간을 절약하며 데이터베이스에서 발생할 수 있는 모든 이상현상을 방지하기 위해 실행하는 데이터 모델링의 과정이다.

주로 단계별로 문제가 있는 테이블의 특정 데이터들을 기존의 다른 테이블로 옮기거나 새로운 테이블을 만들어 옮기는 등 테이블을 분해해가며 이루어진다.

일반적으로 정규화는 데이터 모델을 만들고 난 이후에 직접 데이터베이스를 구현하기 전에 이루어진다.




정규형(Normal Form)

정규형: 정규형은 데이터베이스 테이블이 정규화 과정에서 도달할 수 있는 각 구조적 단계들을 의미한다. 각 정규형은 특정한 데이터 구조를 만족시키기 위한 규칙이나 제약 조건을 정의하며, 데이터의 중복을 줄이고 무결성을 유지하기 위한 목적으로 사용된다.


정규형은 주로 1NF, 2NF, 3NF 등의 각 단계의 숫자를 섞을 약자로 표시되고 순서에 따라 지켜야할 규칙이 누적된다.

예를 들어 2NF는 1NF를 만족하고, 3NF는 1, 2NF를 만족해야 하는 식으로 누적된다.


일반적으로 3NF 이후에도 4NF, 5NF, BCNF, EKNF 등 다양한 단계의 정규형이 존재하지만 데이터베이스를 전문적으로 연구하는 직업이 아니고서는 잘 다룰 일이 없다.

대부분의 경우 3NF까지만 잘 부합한다면 충분히 잘 정규화된 데이터베이스라고 할 수 있다.




제 1 정규화(1NF)

1NF: 테이블 안의 모든 값들이 원자값(나눌 수 없는 하나의 값, Atomic Value)을 갖도록 테이블을 분해해나가는 정규화 과정이다.


idnamecompanycompany_phone_numberaddress
1홍길동NEVER356-213-134서울, 제주
2김철수CACAO409-234-658부산
3박영희SAMSONG397-346-379수원, 용인

예를 들어 위와 같이 한 사람당 여러 개의 주소를 저장할 수 있어 address 컬럼에 여러 개의 값이 들어가 있다면 이는 1NF의 원칙에 위배된다.

그렇다면 어떻게 해당 테이블을 1NF에 부합하게 수정할 수 있을까??



단순히 address 컬럼을 여러 개로 늘린다고 하면 지양되야 하는 수많은 NULL값이 발생할 것이고 몇 개의 address 컬럼을 늘려야 하는지도 명확하지도 못 하며 조회하기에도 까다롭다. 따라서 단순히 컬럼을 늘리는 것 말고 좋은 데이터베이스를 위해 우리는 다른 방법을 사용해야 한다.


idnamecompanycompany_phone_numberaddress
1홍길동NEVER356-213-134서울, 제주
2김철수CACAO409-234-658부산
3박영희SAMSONG397-346-379수원, 용인


address table

iduser_idaddress
11서울
23용인
31제주
42부산
53수원


위와 같이 address 테이블을 새로 만들어 여러 개의 주소를 저장하고 user_id의 FK를 추가하면 1NF도 충족하고 충분히 좋은 데이터베이스 설계를 유지할 수 있다.


제 2정규화(2NF)에 대해 알아보기 전에 먼저 이해해야하는 개념인 '함수 종속성'과 후보키(Candidate Key)에 대해 살펴보자.




함수 종속성

함수 종속성 : 함수 종속성이란 하나의 속성(컬럼)이 다른 속성이 결정되는 데에 결정적인 역할을 하는 관계이다.

예를 들어 y = 2x + 3와 같은 함수 식에서 x에 어떤 값이 들어가냐에 따라 y의 값이 결정되기 때문에 y는 x에 대해 함수 종속성이 있다고 표현할 수 있다.
(x → y)


데이터베이스 테이블 예시를 통해 살펴보자.


이름 (name)나이 (age)직업 (occupation)
김철수30개발자
이영희25디자이너
박민수40마케팅 매니저
최수정35회계사
정우진28엔지니어

이름이 주어지면 해당 인물의 나이와 직업이 고유하게 결정되기 때문에 나이(age)와 직업(occupation)은 이름(name)에 함수 종속성이 있다고 할 수 있다.

(이름 (Name) → {나이 (Age), 직업 (Occupation)})



이행적 함수 종속성

이행적 함수 종속: 이행적 함수 종속성은 마치 3단 논법처럼 하나 이상의 attribute(속성)을 건너서 함수 종속성이 있는 경우이다.


이름 (name)국적 (nationality)대륙 (continent)
김철수한국아시아
마리아스페인유럽
존 스미스미국북아메리카
아야카일본아시아
피에르프랑스유럽

국적(nationality)은 사람(name)에 의해 결정되고 또 어느 대륙(continent)에 사는지는 국적에 의해 결정된다.

(이름 → 국적 → 대륙)




Candidate Key(후보 키)

Candidate Key(후보 키): 하나의 로우(데이터)를 고유하게 식별할 수 있는 속성(컬럼, attribute)들의 최소 집합을 의미한다.


학생 테이블

학번 (StudentNumber)이름 (Name)학과 (Department)
20231001홍길동컴퓨터공학과
20231002김철수전자공학과
20231003박영희기계공학과
20231004이영수수학과
20231005최미나물리학과

위의 테이블에서는 학번은 학생당 1개만 가질 수 있기 때문에 학번이 후보 키가 될 수 있다.



학생 테이블

학생ID (StudentID)강좌ID (CourseID)학기 (Semester)성적 (Grade)
101CSE1012024-1A
101CSE1022024-1B
102CSE1012024-1B+
103CSE1012024-2A-
101CSE1012024-2A

또한 후보 키는 여러 개의 attribute(속성)가 합쳐져 후보 키가 되는 복합 후보 키(Composite Candidate Key)가 되는 경우도 있다.

위의 테이블에서는 학생ID와 강좌ID의 값만으로는 개별 학생을 식별할 수는 없지만 한 강좌에서 학생ID는 중복되지 않는다고 하면 학생ID와 강좌ID를 두 개를 합치면 학생을 식별할 수 있기 때문에 (학생ID, 강좌ID)가 후보 키가 될 수 있다.


Prime Attibute: Candiate Key에 포함된 모든 attirbute

Non-Prime Attribute: Candiate Key 포함되지 않는 모든 attribute




제 2정규화(2NF)

2NF: 2NF를 충족하기 위해서는 1NF에 부합하고 테이블 안의 후보키(candidate key)의 일부분에 대해서만 함수 종속성(부분 함수 종속성)이 있는 non-prime attribute가 없어야 한다.



수강 신청 테이블

학번 (Student ID)과목 코드 (Course Code)교수 이름 (Professor Name)
20230101CS101김교수
20230101MATH202이교수
20230102CS101김교수
20230103BIO303박교수
20230103MATH202이교수

예시 테이블을 살펴보자.

기본 키이자 후보 키가 학번(Student ID)와 과목 코드(Course Code)의 복합 키로 되어 있는데 non-prime attribute인 교수 이름(Professor Name)이 과목 코드(Course Code)에만 종속되기 때문에 부분 함수 종속성이 존재하여 해당 테이블은 2NF를 위배한다.



제2정규형(2NF)을 지키기 위해서는 부분 함수 종속성을 제거해야 한다.

부분 함수 종속성을 제거하는 방법은 간단하다.
후보키의 일부분에만 의존하는 Non-prime attribute를 따로 분리해주면 된다.



수강 신청 테이블

학번 (Student ID)과목 코드 (Course Code)
20230101CS101
20230101MATH202
20230102CS101
20230103BIO303
20230103MATH202


과목 정보 테이블

과목 코드 (Course Code)교수 이름 (Professor Name)
CS101김교수
MATH202이교수
BIO303박교수


만약 해당 속성을 옮겨줄 테이블이 존재한다면 해당 테이블에 옮기고 존재하지 않는다면 지금처럼 새로운 테이블을 만들어 옮기면 된다.




제 3정규화(3NF)

3NF: 3NF는 2NF에 부합하고 동시에 테이블 안의 모든 attribute(속성, 컬럼)들은 오직 Primary Key에 대해서만 함수 종속성이 있어야 한다.



직원 (Employees) 테이블

직원ID (Employee ID)직원 이름 (Employee Name)부서ID (Department ID)부서 이름 (Department Name)부서 위치 (Department Location)
1001김철수D01인사부서울
1002박영희D02재무부부산
1003이민호D01인사부서울
1004조지훈D03마케팅부대구

해당 테이블은 2NF까지는 충족하지만 PK는 직원ID인데에 반해 부서 이름과 부서 위치는 오히려 PK가 아닌 부서ID에 종속되기 때문에 3NF에 위배된다.



이러한 경우도 계속 그래왔던 것처럼 테이블을 분해하여 해결할 수 있다.



직원 (Employees) 테이블

직원ID (Employee ID)직원 이름 (Employee Name)부서ID (Department ID)
1001김철수D01
1002박영희D02
1003이민호D01
1004조지훈D03
  • 기본 키: 직원ID (Employee ID)
  • 외래 키: 부서ID (Department ID)


부서 (Departments) 테이블

부서ID (Department ID)부서 이름 (Department Name)부서 위치 (Department Location)
D01인사부서울
D02재무부부산
D03마케팅부대구
  • 기본 키: 부서ID (Department ID)



비정규화(Denormalization)

비정규화: 비정규화는 데이터베이스의 성능을 개선하기 위해 일부 정규화된 테이블을 의도적으로 비정규화하는 방식이다. 비정규화는 정규화된 데이터베이스 구조를 변경하여 데이터 중복을 허용하거나 조인 연산을 줄이는 방식으로 수행된다. 비정규화는 주로 읽기 성능을 최적화하고, 복잡한 쿼리의 성능을 향상시키기 위한 목적으로 사용된다.




비정규화 방식 예시

  1. 중복 데이터 저장: 자주 조회되는 데이터는 여러 테이블에 중복 저장하여 조인 없이 직접 조회할 수 있습니다.

  2. 집계 테이블: 자주 사용하는 집계 결과를 미리 계산하여 별도의 테이블에 저장합니다. 예를 들어, 매출 집계 테이블을 만들어서 월별 매출을 미리 계산해 저장합니다




비정규화의 장점

  1. 읽기 성능 향상: 비정규화된 데이터베이스는 자주 사용되는 쿼리의 성능을 향상시킬 수 있다. 데이터가 중복 저장되면 조인 연산을 줄일 수 있어 조회 성능이 향상된다.

  2. 쿼리 단순화: 비정규화는 복잡한 쿼리를 단순화할 수 있다. 여러 테이블을 조인하는 대신 단일 테이블에서 필요한 데이터를 직접 조회할 수 있다.

  3. 트랜잭션 성능 개선: 데이터 중복으로 인해 읽기 작업이 빨라지므로, 트랜잭션의 성능이 개선될 수 있다.




비정규화의 단점

  1. 데이터 중복: 데이터 중복이 발생하여 데이터 일관성을 유지하는 것이 어려울 수 있. 데이터 수정 시 여러 테이블을 업데이트해야 할 수도 있다.

  2. 저장 공간 증가: 데이터 중복으로 인해 저장 공간이 증가할 수 있다.

  3. 복잡한 업데이트: 데이터가 중복되어 있기 때문에 업데이트 시 여러 곳에서 수정해야 할 수 있다.




profile
알고리즘, 자료구조 블로그: https://gyun97.github.io/

0개의 댓글