데이터베이스에서 데이터를 처리할 때 성능이라고 하면 조회 성능과 입력/수정/삭제 성능의 두 부류로 구분된다. 이 두 가지 성능이 모두 우수하면 좋겠지만 데이터 모델을 구성하는 방식에 따라 두 성능이 Trade-Off 되어 나타나는 경우가 많이 있다.

| 정규화 | |
|---|---|
| 제1정규형(1NF) | 모든 테이블의 컬럼이 원자값을 가지도록 함. |
| 제2정규형(2NF) | 제1정규형을 만족하고, 기본 키가 아닌 모든 속성이 기본 키에 완전 종속되도록 함. |
| 제3정규형(3NF) | 제2정규형을 만족하고, 기본 키가 아닌 모든 속성이 기본 키에 이행적 종속되지 않도록 함. |



정규화는 데이터베이스 설계의 기본이지만, 모든 경우에 정규화가 항상 최선은 아니다!! 데이터베이스 설계자는 데이터 모델링 과정에서 데이터의 무결성과 성능 간의 균형을 맞추는 것이 중요하다!!
반정규화는 데이터베이스 선능을 최적화하려는 시도로, 특정 상황에서는 효과적이지만, 잘못된 반정규화는 ㅇ히려 성능을 저하시킬 수 있다.




SELECT B.총매각금액, B.총유찰금액
FROM (
SELECT DISTINCT 매각일자
FROM 일자별매각물건
WHERE 매각장소 = '서울 7호'
) A,
매각일자별매각내역 B
WHERE A.매각일자 = B.매각일자;
SELECT B.총매각금액, B.총유찰금액
FROM 매각기일 A, 매각일자별매각내역 B
WHERE A.매각장소 = '서울 7호'
AND A.매각일자 = B.매각일자;
1.데이터 처리량:

참고로, 한 테이블에 인덱스가 많아지면 조회 성능은 향상되지만 데이터 입력/수정/삭제 성능은 저하된다. (즉, 이 예시의 반정규화에서는 조회 성능은 나쁘지 않지만 CUD의 성능이 저하된다는 거다.)

SELECT 모델코드, 모델명
FROM 모델
WHERE
(A유형기능분류코드1 = '01') OR
(B유형기능분류코드2 = '02') OR
(C유형기능분류코드3 = '07') OR
(D유형기능분류코드4 = '01') OR
(E유형기능분류코드5 = '02') OR
(F유형기능분류코드6 = '07') OR
(G유형기능분류코드7 = '03') OR
(H유형기능분류코드8 = '09') OR
(I유형기능분류코드9 = '09');
SELECT A.모델코드, A.모델명
FROM 모델 A, 모델기능분류코드 B
WHERE
(B.유형코드 = 'A' AND B.기능분류코드 = '01' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'B' AND B.기능분류코드 = '02' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'C' AND B.기능분류코드 = '07' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'D' AND B.기능분류코드 = '01' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'E' AND B.기능분류코드 = '02' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'F' AND B.기능분류코드 = '07' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'G' AND B.기능분류코드 = '03' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'H' AND B.기능분류코드 = '09' AND A.모델코드 = B.모델코드) OR
(B.유형코드 = 'I' AND B.기능분류코드 = '09' AND A.모델코드 = B.모델코드);
인덱스는 데이터베이스 테이블에서 검색 성능을 향상시키기 위해 사용하는 데이터 구조이다. 인덱스를 사용하면 특정 조건을 만족하는 레코드를 효율적으로 찾을 수 있다. 이제 인덱스가 검색 성능을 향상시키는 이유와 그 원리는 다음과 같다.

함수적 종속성은 데이터베이스 설계에서 매우 중요한 개념으로, 정규화 과정을 이해하고 수행하는 데 기본이 된다. 이를 통해 데이터의 일관성을 유지하고 중복을 최소화할 수 있다.
예를 들면, 주민등록번호가 주어지면 그에 해당하는 이름, 출생지, 가족 관계가 유일하게 결정된다. 이를 기호로 표시하면 다음과 같다.
주민등록번호 -> (이름, 출생지, 가족 관계)

함수적 종속성에 근거한 정규화는 데이터베이스 설계의 필수 과정이다. 정규화의 목적은 데이터의 중복을 제거하고, 이상현상을 방지하는 것이다. 이를 위해 함수적 종속성을 이용하여 데이터를 적절히 분리하고 배치해야 한다.
위의 예제에서, 사람이라는 엔티티에는 주민등록번호, 이름, 출생지, 호주 속성이 존재한다. 여기서 이름, 출생지, 가족 관계가 주민등록번호에 함수적으로 종속되어, 한 사람의 주민등록번호가 주어지면 그 사람의 이름, 출생지, 가족 관계가 결정된다.
1차 정규화 (1NF: First Normal Form)
1차 정규화는 테이블의 모든 필드가 원자값(atomic value)을 가져야 한다는 것을 의미한다. 즉, 각 필드에는 하나의 값만 존재해야 한다. 이를 통해 중복되는 데이터를 제거하고, 데이터베이스의 무결성을 유지할 수 있다.
잘못된 형태: -- 각 필드에는 하나의 값만 존재해야 한다!
StudentID | Name | Subjects
------------------------------------
1 | John Doe | Math, Science
2 | Jane Smith | Math, English
1NF 형태:
StudentID (PK) | Name | Subject
-------------------------------------
1 | John Doe | Math
1 | John Doe | Science
2 | Jane Smith| Math
2 | Jane Smith| English
잘못된 형태:
EmployeeID | Name | PhoneNumbers
----------------------------------------
1 | Alice Johnson| 123-4567, 234-5678
2 | Bob Smith | 345-6789, 456-7890
1NF 형태:
EmployeeID (PK) | Name | PhoneNumber
--------------------------------------------
1 | Alice Johnson| 123-4567
1 | Alice Johnson| 234-5678
2 | Bob Smith | 345-6789
2 | Bob Smith | 456-7890
2차 정규화 (2NF: Second Normal Form)
2차 정규화는 1차 정규화를 만족하면서, 부분 함수 종속성을 제거하는 것이다. 이는 기본 키가 아닌 열이 기본 키의 부분 집합에 종속되지 않도록 하는 것을 의미한다.
-조건
1NF 형태:
OrderID | ProductID | ProductName | Quantity
-------------------------------------------
1 | 101 | Widget | 10
2 | 102 | Gizmo | 20
잘못된 2NF 형태:
OrderID | ProductID | ProductName | Quantity
-------------------------------------------
1 | 101 | Widget | 10
2 | 102 | Gizmo | 20
2NF 형태:
OrderID | ProductID | Quantity
------------------------------
1 | 101 | 10
2 | 102 | 20
ProductID | ProductName
-----------------------
101 | Widget
102 | Gizmo
1NF 형태
OrderID | ProductID | ProductName | Quantity | Price
----------------------------------------------------
1 | 101 | Widget | 10 | 5.00
1 | 102 | Gizmo | 20 | 10.00
2 | 101 | Widget | 15 | 5.00
2 | 103 | Gadget | 5 | 15.00
2NF형태
OrderID (PK) | ProductID (PK) | Quantity
-----------------------------------------
1 | 101 | 10
1 | 102 | 20
2 | 101 | 15
2 | 103 | 5
ProductID (PK) | ProductName | Price
------------------------------------
101 | Widget | 5.00
102 | Gizmo | 10.00
103 | Gadget | 15.00
3차 정규화 (3NF: Third Normal Form)
3차 정규화는 2차 정규화를 만족하면서, 기본 키가 아닌 열이 다른 기본 키가 아닌 열에 종속되는 경우를 의미한다. (이행적 함수 종속성을 제거 한다는 뜻이다.)
3차 정규화 (3NF: Third Normal Form)
쉽게 말해, A -> B, B -> C가 성립하면 A -> C도 성립하는 경우를 의미한다. 3차 정규화(3NF)는 이러한 이행적 종속성을 제거하여 데이터 무결성을 더욱 강화한다.
2NF 상태의 테이블
StudentID (PK) | Name | CourseID (FK) | CourseName | InstructorID (FK) | InstructorName
----------------------------------------------------------------------------------------------
1 | John Doe | 1001 | Math | 201 | Dr. Smith
2 | Jane Smith | 1002 | English | 202 | Prof. Johnson
3 | Sam Brown | 1001 | Math | 201 | Dr. Smith
위 테이블에서는 CourseID와 InstructorID가 각각 CourseName과 InstructorName에 종속된다. 즉, CourseID -> CourseName, InstructorID -> InstructorName이라는 종속성이 있다.
이때, StudentID가 기본 키입니다. 이 테이블에는 이행적 종속성이 존재한다.
따라서, StudentID -> InstructorName이라는 이행적 종속성이 생긴다. 이러한 이행적 종속성은 데이터 무결성을 해칠 수 있다.
따라서 3차 정규화(3NF)로 변환하여, 이러한 이행적 종속성을 제거하여, 기본 키에 직접 종속된 열들만 남도록 테이블을 분리하면 아래와 같다.
3NF
StudentID (PK) | Name | CourseID (FK)
--------------------------------------------
1 | John Doe | 1001
2 | Jane Smith | 1002
3 | Sam Brown | 1001
CourseID (PK) | CourseName | InstructorID (FK)
----------------------------------------------
1001 | Math | 201
1002 | English | 202
InstructorID (PK) | InstructorName
----------------------------------
201 | Dr. Smith
202 | Prof. Johnson
여기서, CourseID와 InstructorID는 더 이상 StudentID에 이행적으로 종속되지 않는다. 대신, 각 테이블이 직접적으로 기본 키에만 종속되게끔 구조화된다. 즉, CourseName과 InstructorName은 각각 CourseID와 InstructorID에 직접 종속되며, 이로 인해 이행적 종속성이 제거된다.
요약하자면, 3차 정규화는 비기본 키 열이 다른 비기본 키 열에 종속되지 않도록 하여 데이터의 무결성을 유지하고 데이터 중복을 최소화하는 과정이다.
이행적 종속성이 데이터 무결성을 해칠 수 있는 이유는 다음과 같은 상황들에서 발생할 수 있는 문제들 때문이다
이행적 종속성이 있는 2NF 테이블 예시
StudentID | Name | CourseID | CourseName | InstructorID | InstructorName
-----------------------------------------------------------------------------
1 | John Doe | 1001 | Math | 201 | Dr. Smith
2 | Jane Smith | 1002 | English | 202 | Prof. Johnson
3 | Sam Brown | 1001 | Math | 201 | Dr. Smith
이 테이블에서는 CourseID -> InstructorID, InstructorID -> InstructorName이라는 종속성이 존재한다. 따라서 StudentID -> InstructorName이라는 이행적 종속성이 있다. 문제점은 아래와 같다.
Dr. Smith의 이름이 여러 행에 반복적으로 나타난다.Dr. Smith의 이름을 Dr. John Smith로 변경하려면 여러 행을 수정해야 한다. 만약 한 행에서만 수정이 이루어진다면 데이터 불일치가 발생한다.Sam Brown이 테이블에서 삭제되면, Math 강의와 Dr. Smith 강사 정보도 함께 삭제되어야 하는 상황이 발생할 수 있다.위 문제를 해결하기 위해 3차 정규화로 변환(3NF)를 하면 아래와 같이 변한다.
StudentID (PK) | Name | CourseID (FK)
--------------------------------------------
1 | John Doe | 1001
2 | Jane Smith | 1002
3 | Sam Brown | 1001
CourseID (PK) | CourseName | InstructorID (FK)
----------------------------------------------
1001 | Math | 201
1002 | English | 202
InstructorID (PK) | InstructorName
----------------------------------
201 | Dr. Smith
202 | Prof. Johnson
해결된 문제점은 아래와 같다.
InstructorName은 InstructorID 테이블에서 한 번만 저장된다.