제 1 정규형 : 모든 속성은 반드시 하나의 값을 가져야 한다.
다중 값 문제
- [연락처] 라는 속성이 있다고 가정하자.
집전화번호, 휴대폰 번호 1, 2, 3,... 등 다중값(multivalued)이 들어갈수 있을것이다.
이름 | 연락처 |
만쥬 | 010-1234-1234, 02-1234-1234 |
이 경우 어떤 번호가 무엇인지 알 수 없다.
즉, 원하는 속성값을 추출하기 어렵다.
- 명확하지 않은 속성은 다른 유형의 데이터를 포함할 수도 있어 본연의 의미가 퇴색될 수 있다.
이와 같이 데이터를 관리한다면
- 개발의 복잡성 증가
- 속성의 의미 퇴색
- 장기적으로 불안정한 데이터 구조 양산
- 개발의 오류 및 데이터 품질 문제
를 야기할 수 있다.
위와 같은 문제는 엔터티를 추가해 다중값에 대한 문제를 해결할 수 있다. (부모(사람), 자식(연락처) 테이블로 분리)
이처럼 다중값을 제거함으로써 속성을 명확하게 활용한다면 개발의 복잡성을 감소시킬 수 있다.
중복 데이터 문제
- 정규 1유형은 다른 유형의 중복 데이터도 의미할 수 있다.
주문번호 |
# 주문번호 * 상품번호 1 * 상품번호 2 고객명 |
이러한 엔터티가 존재한다면 아래와 같은 문제가 발생할 수 있다.
- 상품을 여러개 주문할 수 없다.
- 상품1, 상품2 모두 빠르게 조회하고 싶다면, 속성마다 인덱스를 추가해야한다.
위와 같은 엔터티는 상품을 2개까지만 주문할 수 있다.
만약 2개 이상을 주문하고 싶다면 속성을 매번 추가해야한다.
속성을 추가한다는 것은 테이블 칼럼을 추가하는 것으로 여러 문제가 발생될 수 있다.
또 인덱스를 추가하면 조회 속도는 빨라질 수 있으나 입럭, 수정, 삭제 속도는 느려질 수 있다.
이러한 경우 주문 - 주문상세 와 같이 엔터티를 추가하면 된다.
제2정규형 : 엔터티의 일반속성은 주식별자 전체에 종속적이어야 한다.
주문번호 | 상품번호 | 상품명 |
00001 | 3 | 일본여행 |
00002 | 5 | 유럽여행 |
00003 | 5 | 유럽여행 |
- 위의 테이블을 보면, 상품번호와 상품명이 중복되는 데이터가 존재한다.
- 하지만, 상품정보는 고객이 주문함으로써 발생하는 매핑 정보로서의 의미를 가진다.
- 상품명은 주문번호와 상관 없이, 상품번호에 의해서만 결정된다.
- 이러한 것을 '종속적' 이라고 한다.
함수종속성 (Functional Dependency)
- 데이터들이 어떤 기준값에 의해 종속되는 현상을 지칭한다.
- 결정자 (DETERMINANT) -> 종속자 (DEPENDENT)
ex) 상품번호 -> 상품명 - 결정자 : 기준값
- 종속자 : 종속되는 값
부분 종속
- 식별자 전체가 아닌 일부에만 종속적인 것
- ex) 상품명
이 때, 상품명은 일부에만 종속적이다.
주문상세의 식별자는 주문번호, 상품번호인데 주문번호에는 종속되지 않는다.
이는 제2정규형을 위배한 것이다.
- 상품명이 변경된다면, 주문상세의 중복된 상품명을 모두 변경해야 한다.
많이 팔린 상품일수록 변경해야할 상품명의 부하도 크게 증가한다. - 주문상세의 상품명을 변경한다 해도, 특정 시점엔 아직 변경되지 않은 상품명이 존재하고, 이 때 들어온 트랜잭션은 일관되지 않는 데이터를 조회하게 된다.
==> 데이터 중복은 정합성에 문제를 발생시킨다.

- 위와 같이 상품 엔터티를 추가하면, 부분 종속성을 제거할 수 있다.
- 상품번호를 매핑키로 활용해 상품명을 확인하는 구조로 관리하면 된다.
- 상품명이 변경되어도, 데이터를 상품 엔터티에서 일원화해 관리하고 있어 중복 데이터에 대한 문제점도 해결할 수 있다.
제 3정규형 : 엔터티의 일반속성 간에는 서로 종속적이지 않는다.

- 고객번호와 고객명은 주문번호에 종속적이라 제2정규형을 만족한다.
- 고객명은 고객번호에 종속적이다.
- 고객번호는 주문전호에 종속적이다.
- 이것을 이행적 종속 (Transitive Dependency) 이라한다.
- 이러한 이행적 종속을 배제하는 것이 제3 정규형이다.
- 고객명이 식별자가 아닌 일반속성에 종속적이라 제 3 정규형을 위배했다.
- 고객명이 변경된다면? 주문 엔터티에 고객명을 모두 갱신해야한다.
이는 주문과는 연관 없는 트랜잭션이다. - 데이터 중복으로 발생하는 문제는 제 2정규형과 동일한 문제가 발생한다.
이러한 문제를 해결하려면 고객 엔터티를 분리해서 관리해야한다.
- 추가로 주문 엔터티에서 고객번호가 Null 허용인 경우는 비회원 주문이 가능한 구조일 수 있다.
앞의 내용들은 이해하기 쉬운 모델로 설명했다고 한다.
비즈니스 도메인이 높은 모델이라면 이렇듯 쉽게 생각해 내기 어려울 수 있다.
그러나 지금까지 처럼 근거가 명확한 기준에 의한 모델링은 더 나은 데이터 설계를 가능하게 해주기 때문에,
정규화를 반드시 해야한다고 한다.
반정규화와 성능
반정규화
- 정규화를 반대로 하는 것으로, 역정규화라고도 한다.
- 반정규화는 성능을 위해 데이터 중복을 허용하는 것이다.
- 하지만, 조회 성능을 향상시킬 수도 있지만 그로인한 입력, 수정, 삭제 성능은 저하될 수 있다.
반정규화의 성능 향상과 저하
- p. 92
- 엔터티에 반정규화를 통해 속성을 추가한다면, 특정경우 조인을 하지 않을 수 있게되어 조회 속도가 향상될 수 있을것이다.
- 그러나 속성 추가로 인해 UPDATE와 같이 불필요한 로직이 추가된다면 배보다 배꼽이 더 큰 경우일 수 있다.
- 정규화한 모델에 적절한 인덱스가 구성되었다면, 이점이 굉장히 미미하기 때문이다.
- 클라우드 환경이라면 과금이 늘어나게 될 수 있다.
- 그럼에도 불구하고 진행해야 할 만한 근거가 뒷받침이 될 때 진행해야 하는것이 반정규화이다.
'학교 > SQLD' 카테고리의 다른 글
[SQLD] 2.1 SQL 기본 (1) | 2024.12.19 |
---|---|
[SQLD] 1.2.2 조인 / 1.2.3 모델이 표현하는 트랜잭션의 이해 / 1.2.4 Null 속성의 이해 / 1.2.5 본질식별자 vs. 인조식별자 (0) | 2024.12.19 |
[SQLD] 1.1.4. 관계 / 1.1.5. 식별자 (0) | 2022.03.09 |
[SQLD] 1.1.2. 엔터티 / 1.1.3. 속성 (0) | 2022.01.10 |
[SQLD] 1.1.1. 데이터 모델링의 이해 (0) | 2022.01.10 |