DB 정규화

Godtaek·2024년 3월 18일
0

CS

목록 보기
3/4

1. 정규화란?

데이터베이스 설계에서 중복을 최소화하고 데이터 무결성을 유지하기 위한 프로세스

논리적 설계 단계에서 발생할 수 있는 종속으로 인한 이상 현상의 문제점을 해결하기 위해, 속성들 간 종속 관계를 분석하여 여러 개의 릴레이션으로 분해하는 과정

  • 이상현상?

    • 데이터베이스의 논리적 설계 시 하나의 릴레이션에 많은 속성들이 존재하여, 데이터 중복과 종속으로 인해 발생되는 문제점

    • 삭제 이상, 삽입 이상, 갱신 이상이 있다.

여러 릴레이션으로 분해해서 테이블 간 중복된 데이터를 허용하지 않는다는 말이다. 무결성을 유지할 수 있고, DB의 저장 용량을 줄일 수 있다는 장점이 있다.

2. 정규화 종류

참고로 NF는 Normal Form의 약자이다.

1. 1NF

한 테이블을 구성하는 모든 컬럼이 원자값만으로 구성되도록하는 정규형이다.
예를 들어보자

PK이름선호운동
1가나축구, 농구
2다라축구, 야구
3마바숨쉬기

위와 같은 테이블을

PK이름
1가나
2다라
3마바
PK운동
1축구
2야구
3농구
4숨쉬기

이렇게 고치는 것이다. 각 컬럼이 원자값을 가지도록 바뀌었다.

2. 2NF

1 정규형을 만족하면서, 테이블을 구성하는 모든 속성이 기본키에 완전 함수 종속이 되도록 분해하는 과정

  • 함수 종속이란?
    • A 컬럼 값을 알면 B 컬럼 값을 알 수 있거나, A 컬럼 값을 변경시킬 때, B 값이 달라진다면 함수적으로 종속되었다고 한다. A -> B
    • 완전 함수 종속 (Fully Functional Dependency): 테이블의 모든 비주요 속성이 주요 키에 대해 완전히 되는 것
    • 부분 함수 종속 (Partial Functional Dependency): 어떤 속성이 주요 키의 일부에만 종속되는 경우
    • 이행적 함수 종속 (Transitive Functional Dependency): A가 B에 함수적 종속이고, B가 C에 함수적 종속인 것. 즉 A -> C인 것

예를 들면 다음과 같다.

Order Number (PK)Customer NumberCustomer NameAddressProduct NumberProduct NameUnit PriceQuantity
1101Hong GildongSeoul201Laptop10001
2102Kim CheolsuBusan202Smartphone8002
3103Lee YeongheeDaegu201Laptop10001

위의 테이블은 2 정규화를 어기고 있다.

Order Number 기본키가 Quantity를 종속하지만, Customer Name, Address 등은 Customer Number에 종속되어 있고, Product Name, Unit Price는 Product Number에 종속되어 있다.

이것을

Customer Number (PK)Customer NameAddress
101Hong GildongSeoul
102Kim CheolsuBusan
103Lee YeongheeDaegu
Product Number (PK)Product NameUnit Price
201Laptop1000
202Smartphone800

이렇게 테이블을 나눠 기본키에 완전 함수 종속시키는 것이 2 정규형이다.

3NF

2 정규형을 만족하면서 테이블 속성들 간 이행적 함수 종속 관계를 분해하여 비이행적 함수 종속이 되도록하는 과정

Order Number (PK)Customer NumberCustomer NameAddressProduct NumberProduct NameUnit PriceQuantity
1101Hong GildongSeoul201Laptop10001
2102Kim CheolsuBusan202Smartphone8002
3103Lee YeongheeDaegu201Laptop10001

이 테이블을 다시 보자. 2 정규형을 어기고 있어서 3 정규형은 당연히 안 되겠지만, Order Number에 많은 컬럼이 종속되어 있다.

Order Number -> Customer Number -> Name, Address...
Order Number -> Product Number -> Product Name, Unit Price....

Customer Number, Product Number만 알면, 나머지 컬럼들은 알 수 있는 내용이기에, 테이블을 나누는 등으로 이행 종속성을 제거한다.

BCNF (보이스-코드 정규형)

3 정규형을 보완하기 위해 만들어진 정규형으로, 3 정규형을 만족하면서 모든 결정자가 후보키가 되도록하는 과정이다.

예시를 들고 싶은데 현실적인 예시가 잘 떠오르지 않는다.
위키백과에서는 3 정규화를 만족하지만 매우 드물게 중복이 제거되지 않을 수 있다고 한다.

잠깐 이 테이블을 보자 사람 근처에 있는 가게를 나타내는 테이블이다.

PersonShop TypeNear Shop
철수편의점GS
철수백화점롯데
영희편의점GS
영희아울렛현대

(Person, Shop Type)으로 복합키를 만들 수 있다. 이 때, Near Shop이 Key가 아님에도 Shop Type의 결정자가 된다.

그런데 애당초 3 정규형을 어기고 있기에...

4NF

4,5 정규화는 고급 정규형이라고 한다.

BCNF를 만족하고 다치 종속을 제거한 것을 4 정규화라고 한다.

다치 종속성이란?

관계 데이터베이스에서 관계 속성 간에 성립하는 종속성의 일종으로, 어떤 속성의 값이 결정되면 다른 속성군의 여러 값의 조가 일의적으로 결정되는 것. 관계 R의 3가지 속성 집합이 각각 X, Y, Z인 경우에, X의 여러 개의 값이 Y의 여러 개의 값에 대응하고, Y 중에서 여러 개의 값도 X의 복수 개의 값에 대응하고 있으나(다 대 다의 사상), Z의 어느 값에도 독립적이면 이때에 Y는 X에 다치 종속이라고 하고 X→→Y로 표기한다.

출처 : TTA 정보통신용어사전

쉽게 말하면 1:N 종속 관계를 의미한다.

과목 테이블

과목강사교재
python귀도반로섬파이썬기초
python귀도반로섬파이썬중급
python사이먼윌리슨파이썬기초
python사이먼윌리슨파이썬중급

위 테이블은 함수적 종속이 존재하지 않는다. 그러나 python 하나의 속성에 강사, 교재는 여러 개의 속성값을 가지고 있다. 즉, 다치 종속이 성립된다.

해당 테이블을

강사 테이블

과목강사
python귀도반로섬
python사이먼윌리슨

교재 테이블

과목교재
python파이썬기초
python파이썬중급

위와 같이 분해하는 것이 4 정규형이다.

5NF

4 정규형을 만족하며, 조인 종속이 후보키를 통해서만 성립이 되도록 하는 정규형이다.

조인 종속은 A 테이블을 B,C로 분해한 뒤, B,C를 join하여 A가 되는 것을 조인 종속이라고 한다.

Order Number (PK)Customer NumberCustomer NameAddressProduct NumberProduct NameUnit PriceQuantity
1101Hong GildongSeoul201Laptop10001
2102Kim CheolsuBusan202Smartphone8002
3103Lee YeongheeDaegu201Laptop10001

이 테이블을 예로 들어보자.

Order Table, Customer Table, Product Table 총 3개의 테이블이 나올 것이다.
Order Table에 Customer Number, Product Number를 외래키로 받는다면, 조인 종속성이 생긴다.

이것을 Order - Customer, Order - Product 중계 테이블을 통해 해결하는 것이 5 정규형이다.

3. 정규화 단점

1~5 정규형을 살펴보았다. DB 정규화를 진행하여 테이블을 분해하면 장점만 있을까?
사실 정규화가 심화되면서 느꼈겠지만 단점이 분명 존재한다.

  1. 설계가 복잡하고 어려워진다.
  2. Join 연산 발생으로 응답시간이 느려진다. (쿼리도 어려워지지)

사실 성능만 위한다면 1번쯤이야.... 진짜 문제는 2번이다.

5 정규형을 생각해보자.

Order 테이블에 Customer, Product를 한 번에 Join하면 되는 걸, Customer, Product를 각각 Join 해야하는 비효율적인 작업을 거쳐야 한다.

SELECT 요청이 중요한 만큼, 적절한 정규형으로 성능과 데이터 무결성을 잡아야 한다. 4, 5 정규형이 고급 정규형인 이유는 아마, 정규형과 성능의 경계선이라고 생각한다.

다만, 1~3정규형 + BCNF 정규형만 지키더라도 심각한 SELECT 성능문제가 존재할 수 있다.
이 때, 쓰기 성능과 용량 이점을 포기해서라도 읽기 성능을 위해 정규화를 어기는 것을 비정규화라고 한다.

4. 마치며

BCNF는 뭘까... 위키백과의 논쟁을 봐도 예시가 떠오르지 않는다.

4 정규화부터는 굳이 사용하지 않는다. 드물게 사용한다. 라는 말이 종종 보인다.

6 정규화가 존재한다는데, 이런 글이 있다.

Now SQL barely supports 5NF, it does not support 6NF at all (I think dportas says the same thing in different words)

6 정규화를 다루지 않는 이유는 하나의 키가 단 하나의 속성과 매치되게 하는 것이기 때문...
그러니까, 각 테이블이 키를 제외하곤 단 하나의 칼럼만을 가져야 한다는 뜻이다.

굳이...굳이....

틀린 부분이 있다면 알려주시면 감사하겠습니다!


참고 자료
참고로 6정규형에 대해서 : https://stackoverflow.com/questions/4824714/would-like-to-understand-6nf-with-an-example
BCNF : https://yaboong.github.io/database/2018/03/10/database-normalization-2/
BCNF 위키 : https://en.wikipedia.org/wiki/Boyce%E2%80%93Codd_normal_form
정규화 전반 : https://superohinsung.tistory.com/111#%EC%A0%9C%203%EC%A0%95%EA%B7%9C%ED%99%94(3NF)-1
깔끔한 예시 : https://mr-dan.tistory.com/10
이상 현상 : https://hoyeonkim795.github.io/posts/%EC%9D%B4%EC%83%81/

profile
성장하는 개발자가 되겠습니다

0개의 댓글