안녕하세요. 데이터베이스 설계의 기본이며, 중요한 주제인 데이터베이스 정규화 (Database Normalization)에 대해서 한 번 알아보도록 하겠습니다.
1. 데이터베이스 정규화 소개
1-1. 개념과 필요성
데이터베이스 정규화란? 데이터베이스 테이블을 구조화하여 데이터의 중복을 최소화하고 데이터 무결성을 유지하는 방법.
정규화는 여러 단계로 이루어지며, 각 단계마다 특정한 규칙이 있습니다. 오늘은 이 규칙들에 대해 자세히 이해해보는 시간을 가집시다.
2. 데이터베이스 정규화의 목적
그렇다면 정규화를 하는 목적이 무엇일까요?
2-1. 데이터 중복 최소화
같은 데이터가 여러 곳에 중복되어 저장되는 것을 방지할 수 있습니다. 데이터가 중복되면 저장 공간을 낭비하고 데이터가 일관되지 못합니다.
만약 여러 테이블에 같은 데이터가 중복되어 저장된다면, 데이터가 변경될 때마다 번거롭게 모든 테이블을 수정해야합니다.
2-2. 데이터 무결성 유지
정규화된 데이터베이스는 데이터 무결성을 유지할 수 있습니다.
무결성 : 데이터의 정확성, 일관성, 유효성이 유지되는 것
2-3. 이상 현상(Anomalies) 방지
데이터베이스 정규화는 데이터 삽입, 삭제, 갱신할 때 발생할 수 있는 이상 현상을 방지합니다. 정규화의 단계가 높아질 수록 이상 현상은 줄어들게 됩니다.
이상 현상(anomalies)이란, 테이블 설계를 잘못하여 생기는 논리적 오류로, 다른 글에서 조금 더 자세히 다루겠습니다.
2-4. 데이터베이스 설계의 명확성
정규화를 통해 데이터베이스 설계가 더 명확해지고 구조화됩니다. 이는 데이터베이스를 쉽게 이해할 수 있어서, 유지보수를 쉽게 만듭니다.
2-5. 쿼리 성능 향상
정규화된 데이터베이스는 인덱스와 함께 사용될 때 쿼리 성능을 향상시킬 수 있습니다.
중복 데이터가 줄어들면서 인덱스 크기가 작아지면 쿼리 처리 속도가 높아집니다. 또한, 무결성이 유지되어 쿼리의 결과가 정확하게 나오게 됩니다.
2-6. 확장성과 유연성
정규화된 데이터베이스는 재설계 시, 더 쉽고 유연하게 문제를 최소화하며 구조를 변경할 수 있습니다. 이러한 데이터베이스는 시스템의 유연성을 높이고, 요구사항에 더 빠르게 대응할 수 있게 합니다.
3. 데이터베이스 정규화 단계
3-1. 제1정규형 (1NF, First Normal Form)
3-1-1. 정의와 규칙
제1정규형(1NF)이란? 테이블의 모든 속성이 원자값(하나의 값)을 가지도록 하는 것.
원자값은 더이상 분해되지 않는 값을 의미합니다.
또한 각 행(row)은 고유한 데이터, 즉 기본키(primary key)를 가져야 합니다.
3-1-2. 예제
우선 database를 만들어줍시다. (앞으로도 계속 사용할 데이터베이스입니다.)
CREATE문을 통해 간단하게 테이블도 생성해주고, 데이터도 삽입해줍니다. 이때, order_id
와 product_id
가 기본키라는 사실을 기억해야 합니다.
SELECT문을 통하여, 생성한 데이터를 확인해봅시다.
어찌됐든 하나의 행(row)당 하나의 원자값을 가지고 있습니다.
비록 중복된 데이터들이 많아서 좋은 테이블은 아니지만, 1NF에 만족합니다.
3-2. 제2정규형 (2NF, Second Normal Form)
3-2-1. 정의와 규칙
제2정규형(2NF)이란? 기본키의 모든 비기본키 속성이 기본키 전체에 완전 함수 종속을 만족하도록 하는 것.
완전 함수 종속은 속성 전체가 하나의 속성을 결정하는 데 필요한 경우를 의미합니다.
높은 단계로 넘어가기 위해선 그 전 단계의 조건을 충족해야 합니다.
그렇기에 2NF가 되기 위해서는 1NF의 조건을 충족해야 합니다.
또, 기본키의 모든 비기본키(기본키가 아닌 속성) 속성이 기본키 전체에 완전 함수 종속을 만족해야 합니다.
조금 쉽게 설명하자면, 테이블에 두 개 이상의 기본키가 있을 때, 비기본키가 모든 기본키들과 관련이 있어야 합니다. 하나의 기본키만 관련되어 있으면 안 됩니다.
그림으로 이해하기 쉽게 그려보겠습니다.
첫 번째 그림은 테이블에 두 개 이상의 기본키가 있을 때, 데이터1과 데이터2가 각각의 기본키에만 관련되어 있습니다.
두 번째 그림은 테이블에 두 개 이상의 기본키가 있을 때, 데이터가 모든 기본키에 교집합 되어있는 것을 확인할 수 있습니다.
이 중 올바른 그림은 바로 두 번째 그림입니다.
하지만 우리가 만든 테이블은 바로 첫 번째 그림의 테이블입니다.
이해하셨나요? 이해하기 어려울 수 있습니다. 예제를 통해서 확실히 살펴보겠습니다.
3-2-2. 예제
아래 테이블은 1NF를 충족하는 테이블입니다.
그러나 2NF에는 충족되지 못합니다. 이유가 무엇일까요?
product_id
와 order_id
는 기본키라는 사실을 생각하고 테이블의 정보를 확인해봅시다.
order_id
가 1일 때, customer_name
은 항상 스마일서브입니다.
또, product_id
가 101일 때, product_name
은 항상 도메인입니다.
그러나 order_id
가 1일 때, product_name
은 항상 도메인인 것만은 아닙니다. 도메인이 되기도 하고, 웹호스팅이 되기도 합니다.
그렇기 때문에 기본키인 product_id
와 order_id
, 각각을 위한 테이블을 만들어보겠습니다.
product
테이블과 order
테이블을 만들어 구분하면 되겠죠? 그리고 quantity
컬럼은 이미 그 어떤 기본키에도 종속되어 있지 않기 때문에, 완전 함수 종속을 만족합니다.
quantity
는 order_id
또는 product_id
중 하나만으로는 결정되지 않고, 모든 기본키가 있어야만, 컬럼의 값을 알 수 있습니다. (이해가 안 되시면 테이블의 값을 확인해보세요.)
그렇기 때문에 quantity
컬럼을 위한 테이블을 하나 더 만들면 될 듯합니다.
전부 완성해주었고, SELECT문을 통해서 확인해봅시다.
이제 2NF에 맞는 테이블이 되었습니다.
3-3. 제3정규형 (3NF)
3-3-1. 정의와 규칙
제3정규형(3NF)이란? 비기본키 간의 관계성이 만족되지 않게 하는 것. (이행 종속성)
높은 단계로 넘어가기 위해선 그 전 단계의 조건을 충족해야 합니다.
그렇기에 3NF가 되기 위해서는 2NF의 조건을 충족해야 합니다.
또, 이행 종속성을 만족시키면 안 됩니다. 이행 종속성이라는 어려운 단어에 너무 두려워하실 필요 없습니다.
이행 종속성이라는 것을 쉽게 풀어서 설명하면 관계성이라는 단어가 될 듯합니다.
쉽게 풀어서, A -> B
, B -> C
일 때 A -> C
를 만족하면 안 됩니다. C는 A여도, B여도 상관 없으면 안 된다는 겁니다.
C -> D
이런 관계는 가능하겠죠. 이해가 좀 되셨나요?
조금 어렵다면 예제를 통해서 확인해봅시다.
3-3-2. 예제
2NF에 충족되는 테이블을 가져오겠습니다.
사실 이 테이블은 이미 3NF에 충족된 테이블입니다. 왜 3NF에 충족될까요? 바로 앞서 말했듯, 모든 테이블에서 이미 이행 종속성을 만족하지 않기 때문입니다.
각 테이블을 살펴보면 비기본키는 하나이기 때문에 비기본키는 다른 비기본키 간에 이행 종속성을 만족하려고 해도, 없기에 만족시킬 수 없습니다.
그렇기 때문에 새로운 테이블로 알아보겠습니다.
이 테이블이 3NF를 위배했습니다. 동시에 2NF도 위배했습니다. 그러나 2NF를 상단에서 다뤘기 때문에 3NF에 대한 내용만 살펴보겠습니다.
customer_id
가 1이면, customer_name
은 ‘스마일서브’입니다.
여기까지 생각했을 때 문제 있는 건 없어 보입니다. 하지만 쿼리문을 자세히 살펴봅시다. customer_id
가 기본키인가요?
아닙니다. 비기본키입니다. 그러나 현재 customer_id
는 customer_name
에 종속되고 있습니다.
아까 3NF의 규칙은 뭐라고 했죠? 비기본키 간의 관계성이 만족되지 않게 하는 것이라고 하였습니다.
그러나 현재 비기본키 간의 관계성이 만족되고 있네요. 이제 어떻게 수정하면 될까요?
customer_id
와 customer_name
을 따로 빼서 테이블을 작성하면 됩니다.
간단한 문제이니 따로 테이블을 작성하지 않고 넘어가겠습니다.
1NF, 2NF, 3NF까지는 기본 정규형입니다. 이외에도 BCNF(코드 정규형), 고급 정규형(4NF, 5NF 등)이 있으나, 글이 길어져 기본 정규형까지만 살펴보겠습니다.
4. 데이터베이스 정규화의 장단점
데이터베이스의 정규화의 목적을 살폈을 때, 장점도 함께 있었기 때문에 단점이 무엇인지 궁금할 수도 있을 것 같습니다.
데이터베이스 정규화의 단점은 크게 다음과 같습니다.
복잡성 증가, 성능 저하 가능성
아무래도 테이블이 많아지고, 컬럼과 데이터의 양이 많아지다 보니 복잡성이 증가하고, 동시에 성능이 저하될 수 있습니다.
간단한 쿼리라면 조금 더 빠르게 검색될 수 있겠지만, 복잡한 조인을 시도할 때는 성능이 저하되어 쿼리 처리 속도가 낮아질 수 있으니 유의하시길 바랍니다.
5. 결론
데이터베이스 정규화는 무척 중요한 개념이고, 아주 기본적인 개념입니다.
미리 염두에 두시고 데이터베이스를 설계하시어, 간단하고 유연한 데이터베이스를 가지셨으면 좋겠습니다.
긴 글 읽어주셔서 감사합니다!