RDB의 설계에서 중복을 최소화 하도록 데이터를 구조화 하는 프로세스를 말한다.
정규화의 목표는 이상이 있는 관계를 재구성 하여 작고 잘 조직된 관계를 생성하는 것에 있다.
이를 위해 데이터를 분해하는 과정이 바로 정규화 작업이다.
각 attribute가 적절한 entity에 배치되고, 각 attribute가 중복된 데이터를 갖지 않도록 한다.
entity: 사람, 장소, 사물 등과 같이 독립적으로 존재하면서 고유하게 식별이 가능한 실세계의 객체
entity set(엔티티 집합): 동일한 attribute(속성)를 가진 엔티티들의 집합
→ 한 회사의 모든 사원들은 employee라는 엔티티 집합을 이룬다.
→ 어떤 사원은 employee, manager라는 두 엔티티 집합에 속할 수 있으므로 엔티티 집합에 속한 요소들이 항상 서로 다르지는 않다.
schema: 데이터를 설명하는 데이터로, 메타데이터라고도 한다.
→ 가령, “홍길동, 2021-12-27” 이라는 데이터가 있을 경우 이는 ‘이름, 생일’ 스키마로 설명할 수 있다.
이는 불필요한 데이터를 제거하여 얻을 수 있다. 하나의 테이블에 모든 정보를 다 넣으면 동일한 정보들이 중복될 수 있는데 그렇게 되면 디스크 공간 낭비가 일어난다.
따라서, FK와 PK로 연결해 사용하면 디스크 공간을 효율적으로 사용할 수 있다.
이상현상은 크게 3가지로 구성 된다.
CRUD가 많이 일어나는 데이터베이스는 정규화
되는 것이 좋으며 그 예로는 “온라인 거래 시스템”과 같은 OLTP(Online Transaction Processing)가 있다. 반면, 분석 리포트 같이 분석과 리포팅을 위해 사용되는 데이터베이스의 경우 연산의 속도가 빨라야 하기 때문에 반정규화
되는 것이 좋다.
반정규화
란?일반적으로, join을 많이 사용해야 하는 대량의 범위의 데이터의 경우 조회에 대한 처리가 중요하므로 ‘속도’가 중요한 요소가 된다. 이 때는 정규화된 시스템의 성능 향상을 위해 역으로 정규화를 수행하게 되는데 이를 ‘반정규화’라고 한다.
정규화(논리 모델링)는 데이터의 저장 비용을 최소화 하는 역할을 담당하고, 반정규화(물리 모델링)은 데이터를 읽어 오는 비용을 최소화 하는 역할을 한다.
정규화를 할 때 주의해야 할 것은 정규화를 너무 잘 해놓으면 데이터를 가져올 때 조인이 많이 필요하게 되며, 정규화를 덜 할 경우 데이터의 중복이 늘어나게 된다. 다시 말해, 정규화를 수행하지 않으면 데이터의 중복이 많아져 하나의 트랜잭션에서 중복된 데이터를 모두 변경해야 하므로 성능이 떨어지게 되는 것이다.
정규화는 1~6정규화까지 있는데 대체로 1~3정규화의 과정을 거친다.
정규화는 Normal Form의 약자를 따서 1정규화의 경우 1NF, 2정규화의 경우 2NF...으로 표기한다.
모든 속성은 반드시 하나의 값을 가져야 한다. 즉, 어떤 relation에 속한 모든 domain이 원자값(atomic value)만으로 이루어져 있다.
→ 가령, “telehone number” attribute의 경우 하나의 전화번호만을 가져야 한다(즉, 여러 개의 전화번호가 들어와서는 안된다).
엔티티에서 똑같은 성격의 attribute가 여러 번 나열되지 않는다.
→ 가령, “회원” 테이블에 “자택 우편 번호”, “회사 우편 번호”와 같이 “우편 번호”라는 동일한 성격의 attribute가 여러 번 나열 되어서는 안된다.
⇒ 이 경우 “회원” 테이블이 아닌 “주소” 테이블을 만들어 구분해야 한다.
기본 키를 사용해 데이터의 각 집합을 고유하게 식별할 수 있다.
Customer
Customer ID | Name | Telephone Num1 | Telephone Num2 |
---|---|---|---|
123 | A | 010-1111-2222 | 010-2345-1223 |
456 | B | 010-4444-1111 | 010-2222-2222 |
789 | C | 010-0000-0900 | 010-2341-2222 |
위와 같은 Customer 테이블이 있다고 할 때, 이는 telephone num1과 telephone num2가 같은 성격의 attribute를 가지므로 제1정규화 조건을 만족하지 못한다.
따라서, 이는 아래와 같이 수정할 수 있다.
1. Name
Customer ID | Name |
---|---|
123 | A |
456 | B |
789 | C |
2. Telephone Number
ID | Customer ID | Telephone Num |
---|---|---|
1 | 123 | 010-1111-2222 |
2 | 123 | 010-2345-1223 |
... | ... |
식별자의 일부에 종속되는 attribute는 제거한다. 즉, 모든 attribute가 완전 함수적 종속을 만족 해야 한다.
→ 어떤 entity의 식별자를 구성하는 attribute가 2개라면 모든 attribute가 식별자에 완전하게 종속적인지 확인해야 한다.
→ {X1, X2} → Y
일 경우 X1과 X2가 Y의 값을 결정한다면 이를 완전 함수적 종속
이라 하며, X1과 X2 중 하나만 Y의 값을 결정한다면 부분 함수적 종속
이라 한다.
⇒ “관련 없는 컬럼은 전부 다른 곳으로 이동해야 한다”라고 이해하면 된다.
회원
id | 회원 번호 |
---|---|
1 | 12345 |
2 | 67890 |
친구
회원 번호(fk) | 친구 회원번호(fk) | 친구 회원명 |
---|---|---|
12345 | 11111 | 밥 |
67890 | 2222 | 오 |
위와 같은 두 개의 테이블이 있을 때 “친구” 테이블에서 “친구 회원명” attribute는 식별자를 구성하는 두 개의 attribute 중에서 “친구 회원번호”에만 종속 관계를 갖고 나머지 “회원 번호”와는 종속 관계가 없다. 따라서 “친구 회원명”은 “회원” entity로 옮겨야 한다. 즉, 회원 테이블에 회원 번호와 회원명이 함께 있으면 되는 것이다.
회원
회원번호(pk) |
---|
회원명 |
직업코드 |
직업명 |
회원 테이블에서 기본키인 회원번호에 ‘회원명’, ‘직업코드’, ‘직업명’ 모두 종속되므로 제 2정규화에 위배되지 않는다. 그러나, 직업명은 직업코드에 의존적이므로 제 3정규화 규칙에 위배된다. 따라서, 엔티티를 분리해야 한다.
1. 직업
직업코드(pk) |
---|
직업명 |
2. 회원
회원번호(pk) |
---|
회원명 |
직업코드(fk) |
키의 종류
유일성: 하나의 키로 특정 행을 바로 찾을 수 있는 성질
→ ex) 주민번호, 학번
최소성: 데이터를 식별하는 데 꼭 필요한 속성들로만 구성되어 있는 성질
→ ex) 주민번호 + 학번 의 경우 최소성을 만족시키지는 않는다. 왜냐하면, 주민번호로
만 특정 행을 바로 찾을 수 있기 때문이다. 반면, 주민번호는 최소성을 만족한다.
Keys | 설명 | 예시 |
---|---|---|
슈퍼 키(Super key) | 유일성을 만족하는 모든 키 | 학번 + 이름, 주민번호 + 학번 |
복합 키(Composite key) | 2개 이상의 속성을 사용한 키 | |
후보 키(Candidate key) | 유일성과 최소성을 만족하는 키 | |
기본 키(Primary key) | - 후보 키에서 선택된 키 | |
- unique한 속성을 지닌다. | ||
대체 키(Surrogate key) | 후보 키 중에 기본 키로 선택되지 않은 키 | |
외래 키(Foriegn key) | - 테이블 간에 기본 키를 참조하는 속성 | |
- 테이블 간의 관계를 나타냄 |
용어
relation: 관계형 데이터베이스에서 정보를 구분하여 저장하는 기본 단위
→ 부서에 관한 정보 저장시 부서 relation이 된다.
domain: relation에서 각각의 attribute(속성)들이 취할 수 있는 같은 타입의 원자 값들의 집합
→ 고등학생의 학년 속성은 1~3까지의 값을 가질 수 있다.
atomic value: 더 이상 분리될 수 없는 값
참고
https://devlog-wjdrbs96.tistory.com/377