안녕하세요. 이번 포스팅엔 DB 정규화에 대한 내용을 정리해보려고 합니다!
관계형 데이터베이스의 설계에서 중복을 최소화하게 데이터를 구조화하는 프로세스를 정규화라고 한다. 데이터베이스 정규화의 목표는 이상이 있는 관계를 재구성하여 작고 잘 조직된 관계를 생성하는 것에 있다.
출처) 위키백과
사전적 정의로는 위와 같이 정리가 되어있습니다!
해당 내용을 좀 더 이해하기 쉽게 정리하자면
데이터의 일관성, 최소한의 데이터 중복, 최대한의 데이터 유연셩을 위한 방법이며 데이터를 분해하는 과정
따라서 불필요한 데이터(data redundancy)를 제거한다.
그에 따라 데이터 저장을 "논리적으로" 한다.
라고 정리할 수 있을 것 같습니다!
그렇다면 이런 정규화를 왜 해야하는지에 대하여 알아보도록 하겠습니다!
1. 불필요한 데이터를 제거, 데이터의 중복을 최소화 하기 위해서
만약 하나의 테이블에 모든 정보를 다 넣게 되면 불필요하게 중복되는 데이터가 저장될 수 있습니다.
그렇다면 불필요하게 더 많은 디스크 공간을 차지하게 될 수 있습니다.
따라서 테이블 간에 FK(외래키)로 PK(기본키)를 연결해 사용하면 디스크 공간을 훨씬 효율적으로 사용할 수 있습니다!
2. 데이터베이스 구조 확장 시 재디자인을 최소화
정규화된 데이터베이스 구조에서는 테이블에 새로운 데이터 형의 추가로 인한 확장시, 그 구조를 변경하지 않아도 되거나 일부만 변경해도 되는 경우가 있습니다.
이는 이 데이터베이스와 연동된 응용 프로그램에 최소한의 영향만을 주게되며 효율적으로 사용할 수 있게 됩니다!
3. 다양한 관점에서의 query를 지원하기 위해서
위의 내용은 1NF와 관련된 내용이므로 밑에서 정리하도록 하겠습니다!
간단하게 얘기하자면 불필요한 정보를 제외하며, JOIN을 통해서 원하는 정보를 가져올 수 있다는 의미인것 같습니다!
4. 무결성 제약조건의 시행을 간단하게 하기 위해서
말그래도 데이터의 정확성, 일관성, 유효성이 유지되는 것을 말합니다.
데이터의 무결성을 유지하는 것은 데이터베이스 관리시스템 (DBMS)의 중요한 기능이며, 주로 데이터에 적용되는 연산에 제한을 두어 데이터의 무결성을 유지하게 됩니다!
5. 각종 이상 현상(Anomaly) 을 방지하기 위해서, 테이블의 구성을 논리적이고 직관적으로 한다.
예시 이미지)
학번 | 과목코드 | 이름 | 연락처 |
---|---|---|---|
2101 | ST01 | 홍길동 | 010-1234-1234 |
2101 | ST02 | 홍길동 | 010-1234-1234 |
2001 | ST01 | 배석재 | 010-2424-2424 |
1901 | ST03 | 김하늘 | 010-3543-4234 |
1) 삭제 이상 (Delete Anomaly)
튜플 삭제시 연쇄 삭제가 발생하는 현상입니다!
예를 들어 2101 학번의 홍길동 학생이 ST01 과목을 수강 취소할 경우,
취소 사유를 물을 수 있는 유일한 정보인 연락처마저 잃게 되는것을 의미합니다!
2) 삽입 이상 (Insert Anomaly)
튜플 삽입시 지정하지 않은 속성값이 NULL을 갖거나, 원하지 않는 자료가 삽입되는 현상입니다!
예를 들어 2101 학번 홍길동 학생의 연락처만 추가하고 싶을 때,
과목코드가 비게되므로 NULL값을 가져 문제가 발생하게됩니다!
3) 갱신 이상 Update Anomaly
데이터 갱신시 일관성 유지가 안되는 현상입니다!
예를 들어 홍길동 학생이 연락처를 바꿨을 경우,
ST01, ST02 모두 갱신해야하는데 ST01만 갱신할 경우 발생하게 됩니다!
위와 같은 이유로 정규화를 진행하게 됩니다!
그렇다면 정규화는 어떤 과정으로 진행되게 되는지 알아보도록 하겠습니다!
위와 같이 진행되며 보통 1NF ~ 3NF까지 진행하거나 BCNF단계까지 진행한다고 합니다!
테이블(Relation)이 1NF를 만족했다는 것은 아래 세 가지 조건를 만족했다는 것을 의미하게 됩니다!
예제를 통해 살펴보면 아래 테이블(Relation)은 위의 1,2,3번 조건 중 1번 조건를 만족하지 못한 사례입니다!
위의 테이블을 보게되면 전화번호를 여러개 가지고 있기 때문에 이는 원자값만으로 구성되어 있지 않게 되고, 이는 1NF를 위반한 것이 됩니다!
해당 테이블은 전화번호 그룹이 반복되는 경우이며 2번 조건를 위반한 사례입니다.
따라서 이를 재디자인 할 필요가 있으며, 아래는 제 1정규화를 만족시키기 위해 바꾼 디자인입니다!
1번과 2번의 조건을 만족시키기위해 재디자인 하였지만 Relation은 ID가 더 이상 고유하게 식별할 수 있는 키가 아니란 것을 확인할 수 있습니다.
따라서, 3번 조건을 만족하기 위해 아래와 같이 테이블을 나눌 수 있게 됩니다!
위의 디자인은 Customer Name과 Customer Telephone Number가 One-to-Many의 관계를 형성하게 됩니다.
따라서 기본 키를 사용하여 관련 데이터의 각 집합을 고유하게 식별할 수 있게 되고 중복되는 데이터를 최소화 할 수 있게 되었습니다!
2NF를 수행 했을 경우 테이블의 모든 컬럼이 완전 함수적 종속을 만족하게 됩니다.
(부분 함수적 종속을 모두 제거되었으므로!)
이를 이해하기 위해서는 부분 함수적 종속과 완전 함수적 종속이라는 용어를 알아야 한다.
그렇다면 예시를 통해 살펴보도록 하겠습니다!
위에서 Model과 Manufacturer를 알면 Model Full Name 필드를 아예 유지하지 않거나 참조하지 않아도 결정되기 때문에, {Model, Manufacturer} -> Model Full Name 이라고 할 수 있게됩니다.
하지만 {Model, Manufacturer} -> Manufacturer Country에서 Model과 Manufacturer Country는 아무런 연관 관계가 없기 때문에, Manufacturer Country는 Manufacturer 만이 종속관계에 있게 되고 이를 부분 함수 종속이라고 하게 되는 것입니다.
위에서 부분 함수 종속을 제거 하게 되면, 아래와 같은 그림이 됩니다!
따라서 위와 같은 내용을 바탕으로 재 디자인 하게 되면,
위와 같이 디자인되게 되고, 2NF를 만족하게 된 테이블이 됩니다!
테이블(Relation)이 제 3정규형을 만족한다는 것은 아래 두 가지 조건을 만족하는 것을 의미하게 됩니다!
아래는 두 번째 조건이 위반된 사례입니다.
위 테이블에서 { Tournament, Year }가 후보키가 됩니다. 하지만 Winner Date of Birth은 기본키가 아닌 속성인 Winner를 거쳐 { Tournament, Year }에 의존하고 있는 것을 알 수 있는데, 이는 3NF를 위반한 것이 됩니다!
따라서 테이블을 아래와 같이 둘로 나누어 줄 수 있습니다.
위와 같이 테이블을 디자인 하게되면 본래 Winner Date of Birth가 Winner를 거쳐 { Tournament, Year }를 의존하게 되는 이행적 함수 종속 관계가 아닌 Date of Birth -> Winner가 되고, Winner -> { Tournament, Year }가 되면서 완전 함수적 종속 관계가 되게 됩니다!
BCNF는 3NF를 만족하면서 모든 결정자가 후보키 집합에 속한 정규형입니다.
위의 예시로 살펴 보겠습니다.
후보키는 수퍼키중에서 최소성을 만족하는 건데, 이 경우 { 학생, 과목 }이 후보키가 됩니다!
근데 해당 테이블의 경우 교수가 결정자입니다.
그 이유는, 교수가 한 과목만 강의할 수 있다고 가정할 때, 교수가 정해지면 과목이 결정되기 때문입니다.
따라서 교수는 수퍼키가 되게 되고, 이 경우에 BCNF를 만족하지 못한다.
이를 해결하기 위해서는 테이블을 분리해야 합니다.
위와 같이 테이블을 재디자인 함으로써 Mr.Sim이 강의하는 과목명이 바뀌었다면 두 개의 로우를 갱신하는것을 방지할 수 있게 됩니다!
지금까지 정규화의 목적과 장점 및 과정, 1NF ~BCNF 정규형까지 정리해 보았습니다!
그렇다면 이러한 정규형을 사용함으로써 단점은 무엇이 있을지 알아보겠습니다!
Relation의 분해로 인해 Relation 간의 연산(JOIN 연산)이 많아져서 질의에 대한 응답 시간이 느려질 수 있게 됩니다!
이러한 단점에 대한 대응책으로는 반정규화를 적용하는 방법도 있습니다!
반정규화는 정규화된 엔티티, 속성, 관계를 시스템의 성능 향상 및 개발과 운영의 단순화를 위해 중복 통합, 분리 등을 수행하는 데이터 모델링 기법 중 하나이다.
위와 같이 설명할 수 있고
위의 상황에서 사용되게 되고 일반적으로 조회에 대한 처리 성능이 중요하다고 판단될 때
부분적으로 반정규화를 고려하게 된다고 합니다!
이상으로 DB 정규화와 비정규화에 대한 포스팅을 마치도록 하겠습니다!
참고 사이트)
https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/Database#part-1-5-database
https://wkdtjsgur100.github.io/database-normalization/
정규화 잘 정리되어 있어서 덕분에, 잘 이해해 갑니다!