DB 정규화 1부(정규화 개념, 1NF, 2NF)

조현근·2022년 12월 14일
0
post-thumbnail

영상을 보고 정리한 내용입니다!
FD를 사용해 DB를 정규화하는 방법에 대해 알아보겠습니다.
FD 포스트

DB 정규화(normalization)

데이터 중복과 insertion, update, deletion anomaly를 최소화하기 위해 일련의 normal forms(NF)에 따라 relational DB를 구성하는 과정

Normal form(NF)란?

정규화 되기 위해 준수해야 하는 몇 가지 rule이 있는데, 이 각각의 rule을 normal form(NF)라 부름

DB 정규화 과정

init table -> 1NF -> 2NF -> 3NF -> BCNF -> 4NF -> 5NF -> 6NF
처음부터 순차적으로 진행하며 normal form을 만족하지 못하면 만족하도록 테이블 구조를 조정함
앞 단계를 만족해야 다음 단계로 진행할 수 있음.
예를들어 어떤 테이블이 3NF를 만족하면, 1NF, 2NF도 만족하고 있는 것.

  • 1NF, 2NF, 3NF, BCNF까진 FD와 key만으로 정의되는 normal form.
  • 3NF까지 도달하면 정규화 됐다고 말하기도 함
  • 보통 실무에선 3NF 또는 BCNF까지 진행(많이 해도 4NF까지만 진행)

DB 정규화 예제

bank_nameaccount_numaccount_idclassratioempl_idempl_namecard_id

위와 같은 attribute를 가지는 테이블을 통해 정규화를 공부해보자.
테이블은 다음과 같은 규칙을 가진다.

  • 임직원의 월급 계좌를 관리하는 테이블이다.
  • 월급 계좌는 국민은행이나 우리은행 중 하나(bank_name)
  • 한 임직원(empl_id)이 하나 이상의 월급 계좌를 등록하고 월급 비율(ratio)을 조정할 수 있다.
  • 계좌마다 등급(class)이 있다.
    • 국민: STAR -> PRESTIGE -> LOYAL
    • 우리: BRONZE -> SILVER -> GOLD
  • 한 계좌(account_num)는 하나 이상의 현금 카드(card_id)와 연동될 수 있다.

table의 key

super key

table에서 tuple들을 unique하게 식별할 수 있는 attribute의 집합

(candidate) key

어느 한 attribute라도 제거하면 unique하게 tuble을 식별할 수 없는 super key

위 테이블에선 {account_id}, {bank_name, account_num}가 key가 된다.
({account_id, bank_name, account_num}은 super key이지만 key는 아님!)

primary key

table에서 tuple들을 unique하게 식별하려고 선택된 (candidate) key

위 테이블에선 attribute 수가 1개인 {account_id}로 선택하자(꼭 그래야 하는건 아니지만 attribute 수가 적을 수록 관리가 쉬움).

prime attribute

임의의 key에 속하는 attribute

위 테이블에선 account_id, bank_name, account_num이 된다.

non-prime attribute

어떤 key에도 속하지 않는 attribute
즉 prime attribute를 제외한 나머지

functional dependency

{account_id} -> {bank_name, account_num, class, ratio, empl_id, empl_name, card_id}

{bank_name, account_num} -> {account_id, class, ratio, empl_id, empl_name, card_id}

{empl_id} -> {empl_name}

테이블 규칙 상 국민은행, 우리은행만 bank_name으로 가능한데, 두 은행의 등급(class)는 서로 다름. 이런 규칙에 의해 아래 FD도 만족함
{class} -> {bank_name}

Normalization

테이블에 아래와 같이 데이터가 들어가 있을때 정규화를 진행해보자.

bank_nameaccount_numaccount_idclassratioempl_idempl_namecard_id
Woori010-9231-1121a11BRONZE0.1e1Sonyc101
Woori102-992-180125a12SILVER0.2e1Sonyc102
Kookmin010-9231-1121a13LOYAL0.7e1Sonyc103
Kookmin010-1221-1732a21LOYAL1e2Messic201, c202

총 2명의 임직원(Sony, Messi)가 있고, Sony는 총 3개의 계좌에 월급을 나눠 받도록 되어있다.

1NF

attribute의 value는 반드시 나눠질 수 없는 단일한 값이어야 한다.
Messi의 card_id가 2개임으로 1NF를 위반하고 있음.

우선 아래처럼 row를 분리해 해결할 수 있음.

bank_nameaccount_numaccount_idclassratioempl_idempl_namecard_id
Woori010-9231-1121a11BRONZE0.1e1Sonyc101
Woori102-992-180125a12SILVER0.2e1Sonyc102
Kookmin010-9231-1121a13LOYAL0.7e1Sonyc103
Kookmin010-1221-1732a21LOYAL1e2Messic201
Kookmin010-1221-1732a21LOYAL1e2Messic202

이렇게 하면 1NF 문제는 해결되지만 중복 데이터가 생기고 primary key도 변경을 해야 한다(primary key인 account_id가 중복되어 더 이상 다른 attribute을 식별하지 못하게 됨).
또한 ratio 부분도 이상하게 된다.

우선 primary key는 card_id를 추가함으로써 해결할 수 있다.
(candidate) key는 {account_id, card_id}, {bank_name, account_num, card_id}로 바뀌게 된다.
non-prime attribute는 class, ratio, empl_id, empl_name가 된다.

{account_id, card_id}

근데 가만히 살펴보면 non-prime attribute는 account_id, card_id 두 개 모두에 의존적일 필요가 없다. account_id에만 의존적이여도 되는 값들이다.
즉 모든 non-prime attribute들이 {account_id, card_id}에 partially dependent 하다.

이는 {bank_name, account_num, card_id}인 경우도 똑같다. 설명은 생략한다.

2NF

모든 non-prime attribute는 모든 key에 fully functionally dependent 해야 한다.
우리의 테이블에선 card_id라는 attribute 때문에 이런 문제가 발생했다. 따라서 테이블을 분리해서 해결해 보겠다.

문제가 되는 card_id를 분리하자.

ACCOUNT_CARD

account_idcard_id
a11c101
a12c102
a13c103
a21c201
a21c202

이렇게 card_id를 분리해내면 원래 테이블을 다음과 같이 줄일 수 있다.

EMPLOYEE_ACCOUNT

bank_nameaccount_numaccount_idclassratioempl_idempl_name
Woori010-9231-1121a11BRONZE0.1e1Sony
Woori102-992-180125a12SILVER0.2e1Sony
Kookmin010-9231-1121a13LOYAL0.7e1Sony
Kookmin010-1221-1732a21LOYAL1e2Messi

그리고 이제 EMPLOYEE_ACCOUNT 테이블이 2NF를 만족함을 알 수 있다.

{account_id} -> {bank_name, account_num, class, ratio, empl_id, empl_name}
{bank_name, account_num} -> {account_id, class, ratio, empl_id, empl_name}
모두 fully FD가 된다.

ACCOUNT_CARD 역시
{card_id} -> {account_id}가 fully FD 임으로 2NF를 만족한다!

profile
안녕하세요!

0개의 댓글