데이터 모델링과 SQL
정규화 vs 반정규화
정규화 : 데이터베이스에서 데이터를 효율적으로 저장하고 중복을 최소화 하기 위해 테이블을 구조화 하는 과정. 정규화의 주된 목표는 데이터 일관성을 유지하고 데이터 저장소의 무결성을 보장하는 것
반정규화: 반정규화는 성능 향상을 위해 정규화된 데이터베이스 구조를 일부러 역행하는 과정입니다. 정규화된 구조는 데이터 무결성을 유지하는 데 도움이 되지만 쿼리 성능이 떨어질 수 있습니다. 반정규화는 이러한 성능 문제를 해결하기 위해 데이터를 중복 지정하거나, 데이터 조인을 줄이는 등의 방법을 사용
정규화
정규화를 하면 일반적으로 조회 성능은 향상되거나 하락(테이블이 많이 분리되기 때문에 원하는 결과를 얻으려면 많은 join을 해야함)하기도 하지만, 입력 / 수정 / 삭제 성능은 일반적으로 향상
1.제1정규형(1NF, First Normal Form) : 모든 속성의 속성값은 1개.(각 열에는 단일 값만 존재)

-유사한 속성이 반복되는 경우도 제1정규형위반

제2정규형(1NF, Second Normal Form): 1NF를 만족하고 기본키가 아닌 모든 열이 기본키에 완전 종속 적이어야 합니다. 즉 부분 종속성을 제거해야 합니다.
주 식별자가 복합 식별자인 경우 일반속성이 주 식별자에 부분적으로 종속되는 경우는 제2정규형을 만족허지 않는것.

-이 테이블은 2NF를 만족하지 않습니다. 왜냐면 StudentName은 StudentID에만 종속되고CourseName과 Instructor는 CourseID에만 종속되기 때문입니다.
-이는 부분 함수 종속성을 나타내며, 다음과 같은 문제가 발생할 수 있습니다.
1.데이터 중복 : 학생 이름, 과목 이름, 감사 정보가 반복됩니다.
예를들어 "Math"과목은 여러 번 반복되며, 이는 데이터 저장 공간을 낭비합니다.
2.데이터 불일치 : 중복된 데이터가 일관되지 않게 업데이트될 위험이 있습니다. 예를 들어 "Math"과목의 강사가 "Dr.Smith"에서"Dr.Brown"으로 변경될 경우, 모든 관련 레코드를 업데이트 해야합니다. 하나라도 빠드리면 데이터가 불일치 하게 됩니다.
3.데이터 무경성 문제 : 데이터 삽입, 수정, 삭제 시 무결성 문제가 발생할 수 있습니다. 예를 들어 새로운 학생이 등록될 떄, 과목정보가 필요 없어도 기본 키 제약 조건을 만족시키기 위해 과목 정보를 입력해야 합니다.
Ex) 새로운아이디가 추가가되었을때 아직 수강을 하고있지 않을때? Null해줘야하느데 courseID는 null이 들어갈수없음..따라서 뭐라도 넣어야하느데 이러면 데이터 무결성 문제가 생김

제3정규형(3NF, Third Normal Form)

이 구조는 2NF를 만족합니다. 그러나 CourseNAme과 Instructor 가 일반 속성 CourseID에 종속 되므로 이행적 종속성을 제거하기 위해 3NF를 만족시켜야 합니다.

반정규화
반정규화는 데이터베이스 설계 과정에서 정규화된 데이터 구조를 의도적으로 일부 되돌리는 작업을 말합니다. 이는 주로 성능 최적화와 쿼리 성능 향상을 위해 수행됩니다. 반정규화는 데이터의 중복을 허용하여 데이터베이스의 읽기 성능을 높이고 조인 연산의 부담을 줄이기 위해 사용됩니다.
반정규화의 장점
1. 성능향상: 데이터 조회 시 조인 연산을 줄임으로써 쿼리 성능이 향상됩니다.
2.간단한 쿼리 : 데이터가 하나의 테이블에 모여 있으므로 쿼리가 단순해지고 유지보수가 쉬워집니다.
3.효율성: 데이터가 중복되어 저장되므로 캐시 효율성이 높아집니다.
반정규화의 단점
1.데이터중복:데이터가 중복 저장되므로 저장 공간이 증가하고, 데이터 불일치 가능성이 높아집니다.
2.데이터 무결성:중복된 데이터를 일관되게 유지하기 어려워질 수 있습니다.
3.복잡한 업데이트: 데이터가 여러 위치에 중복되어 있으므로, 데이터를 삽입, 수정, 삭제할 때 복잡성이 증가합니다.
반정규화의 종류
테이블 반정규화의 종류
테이블 병합:1:1 관계의 테이블 병합, 1:M관계 테이블 병합, 슈퍼/서브 타입 테이블 병합
테이블 분할: 테이블 수직 분할, 테이블 수평 분할
테이블 추가 : 중복 테이블 추가, 통계 테이블 추가, 이력 테이블 추가, 부분 테이블 추가
컬럼 반정규화의 종류(테이블 반정규화와는 다르게 단일 테이블 내에서 성능 최적화)
중복 칼럼 추가
파생 칼럼 추가
이력 테이블 칼럼 추가
1:1관계 테이블 병합 : 1:1 관계는 한 테이블의 각 행이 다른 테이블의 단 하나의 행과만 관련되는 경우입니다. Ex)이름-주민번호, 주 식별자가 한 테이블의 각 행에 대해 고유하며, 다른 테이블의 각 행에 대해 고유한 경우

1:M관계 테이블 병합 : 1:N 관계는 한 쪽 엔티티가 관계를 맺은 엔티티 쪽의 여러 객체를 가질 수 있는 것을 의미(ex)부모-자식, 사장-직원

슈퍼/ 서브 타입 테이블 병합 : 슈퍼타입은 공통 속성을 정의한 부모 테이블입니다. 서브타입은 슈퍼 타입을 상속받아 더 구체적인 특성을 가지는 자식 테이블입니다.

테이블 분할: 테이블 수직 분할을 하면 1:1 관계의 테이블이 생긴다

테이블 분할 : 테이블 수평 분할을 하면 특정 기준으로 별도의 엔터티로 분할한다

테이블 추가 : 중복 테이블 추가 - 중복 테이블 추가는 자주 조회되는 데이터를 중복 저장하여 조회 성능을 높이는 방법
중복 테이블을 통해서 카테고리와 제품을 함께 조회할 때, 조인 없이 빠르게 데이터를 조회할 수 있습니다.
테이블 추가 : 통계 테이블 추가는 복잡한 집계 연상을 사전에 계산하여 저장하는 방법

이 테이블을 통해 월별 총 판매량을 빠르게 조회할 수 있습니다.
테이블추가 : 이력테이블 추가는 데이터의 변경 이력을 관리하기 위해 사용됩니다.

이 테이블을 통해 직원의 직무와 급여 변경이력을 관리할 수 있습니다.
테이블 추가 : 부분 테이블 추가는 자주 사용하는 데이터의 부분 집합을 별도의 테이블로 저장하여 성능을 최적화 하는 방법입니다.

이 테이블을 통해 배송 완료된 주문만 빠르게 조회할 수 있습니다.
중복 칼럼 추가는 자주 조회되는 정보를 동일한 테이블에 중복 저장하여 조인 없이 데이터를 빠를게 조회할 수 있도록 하는 방법

CustomerName을 중복 칼럼으로 추가하여, 주문 테이블만으로도 고객이름을 빠르게 조회 할 수 있게 합니다.
파생칼럼 추가는 기존 칼럼의 값을 기반으로 계산된 값을 저장하여 쿼리 성능을 향상시키는 방법입니다. 주로 계산이나 변환이 자주 필요한 겨우에 사용됩니다

여기서 TotalPrice는 UnitPrice와Quantity를 곱한 값으로 계산되어 저장됩니다. 이를 통해 총 가격을 조회 할 때마다 계산하지 않고 바로 접근할 수 있습니다.
이력 칼럼 추가는 데이터의 변경 이력을 관리하기 위해 칼럼을 추가하는 방법입니다. 주로 데이터의 변경 사항을 추적하고 과거 데이터를 조회할 필요가 있을 때 사용합니다.

여기서 PositioStartDate와 PositionEndDate 는 직원의 직무 시작과 종료 날짜를 기록하여, 이력을 추적할 수 있도록 합니다.
