데이터베이스 정규화 (Normalization)

데이터베이스 설계에서 정규화(Normalization)는 데이터를 효율적으로 저장하고 관리하기 위해 테이블을 구조화하는 과정입니다. 정규화는 데이터의 중복을 최소화하고 데이터 무결성을 보장하는 데 중요한 역할을 합니다. 이 글에서는 정규화의 기본 개념과 이를 실제로 데이터베이스에 적용하는 방법을 상세히 설명하겠습니다.

1NF: 나눌 수 없는 단일 값 (First Normal Form)

첫 번째 정규형(1NF)에 부합하기 위해서는 모든 컬럼이 나눌 수 없는 단일 값을 가져야 합니다. 즉, 각 셀에는 하나의 값만 있어야 합니다.

예시

다음은 1NF를 만족하지 않는 테이블의 예입니다:

사용자 테이블:
+----+--------------+
| ID | phone_numbers|
+----+--------------+
|  1 | 010-1234-5678, 010-9876-5432 |
+----+--------------+

위 테이블에서 phone_numbers 컬럼은 여러 개의 전화 번호를 저장하고 있습니다. 이는 1NF를 위반하는 예입니다. 이를 1NF로 정규화하려면 phone_numbers 컬럼을 분리하여 새로운 테이블을 생성해야 합니다.

사용자 테이블:
+----+
| ID |
+----+
|  1 |
+----+

전화번호 테이블:
+------------+--------------+
| user_id    | phone_number |
+------------+--------------+
| 1          | 010-1234-5678|
| 1          | 010-9876-5432|
+------------+--------------+

나눌 수 없는 단일 값 기준

나눌 수 없는 단일 값의 기준은 데이터의 사용 방식에 따라 달라질 수 있습니다. 예를 들어, 문자열 "cat"은 문자 "c", "a", "t"로 나눌 수 있지만, 일반적으로 이러한 분할은 의미가 없습니다. 데이터베이스 설계에서는 데이터를 사용할 때 온전히 그 단위 자체로 사용하는지를 고려해야 합니다.

서로 다른 값이 저장된 경우

컬럼에 서로 다른 여러 값이 저장된 경우에도 1NF를 위반할 수 있습니다. 예를 들어, 이름을 저장하는 name 컬럼에 성과 이름이 함께 저장된 경우를 생각해 봅시다.

사람 테이블:
+----+-------------+
| ID | name        |
+----+-------------+
|  1 | John Doe    |
+----+-------------+

이 경우 name 컬럼을 first_namelast_name 컬럼으로 분리해야 1NF를 만족할 수 있습니다.

사람 테이블:
+----+-----------+----------+
| ID | first_name| last_name|
+----+-----------+----------+
|  1 | John      | Doe      |
+----+-----------+----------+

2NF: 부분적 함수 종속성 제거 (Second Normal Form)

두 번째 정규형(2NF)은 테이블이 1NF에 부합하고, 모든 non-prime attribute가 전체 candidate key에 대해 완전 함수 종속성을 가지도록 합니다. 이는 partial dependency를 제거하는 것을 의미합니다.

예시

다음은 1NF를 만족하지만 2NF를 만족하지 않는 테이블의 예입니다:

상품 테이블:
+----+--------+--------+----------+-------+--------+------------+
| ID |  name  | brand  | brand_country | price | designer | designer_country |
+----+--------+--------+----------+-------+--------+------------+
|  1 | Shirt  | Nike   | USA      | 50    | John   | USA        |
+----+--------+--------+----------+-------+--------+------------+

brand_countrybrand에 대해 부분 함수 종속성을 가집니다. 이를 2NF로 정규화하기 위해 brand_country를 분리하여 별도의 테이블로 만들어야 합니다.

상품 테이블:
+----+--------+--------+-------+--------+
| ID |  name  | brand  | price | designer|
+----+--------+--------+-------+--------+
|  1 | Shirt  | Nike   | 50    | John   |
+----+--------+--------+-------+--------+

브랜드 테이블:
+----+--------+--------------+
| ID | brand  | brand_country|
+----+--------+--------------+
|  1 | Nike   | USA          |
+----+--------+--------------+

Candidate Key와 Non-Prime Attribute

  • Candidate Key: 유일하게 레코드를 식별할 수 있는 속성 또는 속성의 조합.
  • Non-Prime Attribute: Candidate Key에 속하지 않는 속성.

부분 함수 종속성 찾기

예를 들어, 상품 테이블에서 name, brand, size가 합쳐져 하나의 상품을 식별할 수 있는 Candidate Key입니다. 하지만 brand_countrybrand에만 종속됩니다. 이를 해결하기 위해 다음과 같이 테이블을 분리합니다:

상품 테이블:
+----+--------+-------+--------+
| ID |  name  | price | designer|
+----+--------+-------+--------+
|  1 | Shirt  | 50    | John   |
+----+--------+-------+--------+

브랜드 테이블:
+----+--------+--------------+
| ID | brand  | brand_country|
+----+--------+--------------+
|  1 | Nike   | USA          |
+----+--------+--------------+

3NF: 이행적 함수 종속성 제거 (Third Normal Form)

세 번째 정규형(3NF)은 테이블이 2NF에 부합하고, 모든 non-prime attribute이 primary key에 대해 직접적인 함수 종속성을 가지도록 합니다. 이는 transitive dependency를 제거하는 것을 의미합니다.

예시

다음은 2NF를 만족하지만 3NF를 만족하지 않는 테이블의 예입니다:

상품 테이블:
+----+--------+--------+-------+--------+--------+
| ID |  name  | brand  | price | designer | designer_country|
+----+--------+--------+-------+--------+--------+
|  1 | Shirt  | Nike   | 50    | John   | USA    |
+----+--------+--------+-------+--------+--------+

designer_countrydesigner에 종속됩니다. 이를 3NF로 정규화하기 위해 designer_country를 분리하여 별도의 테이블로 만들어야 합니다.

상품 테이블:
+----+--------+--------+-------+--------+
| ID |  name  | brand  | price | designer|
+----+--------+--------+-------+--------+
|  1 | Shirt  | Nike   | 50    | John   |
+----+--------+--------+-------+--------+

디자이너 테이블:
+----+---------+--------------+
| ID | designer| designer_country |
+----+---------+--------------+
|  1 | John    | USA          |
+----+---------+--------------+

비정규화 (Denormalization)

비정규화는 성능 개선을 위해 정규형을 지키지 않는 구조로 변경하는 것을 의미합니다. 정규화를 통해 데이터가 여러 테이블로 분리되면 조인 연산이 많아져 성능이 저하될 수 있습니다. 비정규화를 통해 데이터를 한 테이블에 저장하면 조회 속도가 빨라질 수 있습니다.

예시

정규화된 테이블 구조:

상품 테이블:
+----+--------+--------+-------+
| ID |  name  | brand  | price |
+----+--------+--------+-------+
|  1 | Shirt  | Nike   | 50    |
+----+--------+--------+-------+

브랜드 테이블:
+----+--------+--------------+
| ID | brand  | brand_country|
+----+--------+--------------+
|  1 | Nike   | USA          |
+----+--------+--------------+

디자이너 테이블:
+----+---------+--------------+
| ID | designer| designer_country |
+----+---------+--------------+
|  1 | John    | USA          |
+----+---------+--------------+

비정규화된 테이블 구조:

상품 테이블:
+----+--------+--------+----------+-------+--------+------------+
| ID |  name  | brand  | brand_country | price | designer | designer_country |
+----+--------+--------+----------+-------+--------+------------+
|  1 | Shirt  | Nike   | USA      | 50    | John   | USA        |
+----+--------+--------+----------+-------+--------+------------+

비정규화를 할 때는 데이터의 중복으로 인한 문제점을 인지하고, 적절한 상황에서만 적용해야 합니다.

비정규화를 고려할 때

  • 데이터가 너무 퍼져있어서 조회 연산의 성능 문제가 심각한 경우.
  • 테이블을 삽입, 업데이트, 삭제하는 것보다 조회하는 용도로만 사용되는 경우.
profile
대학생

0개의 댓글