diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..756bebc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+# IntelliJ IDEA
+.idea/
+**/.idea/
+*.iml
+*.iws
\ No newline at end of file
diff --git a/Computer Science/Database/Database.md b/Computer Science/Database/Database.md
index bf0f095..c9e96db 100644
--- a/Computer Science/Database/Database.md
+++ b/Computer Science/Database/Database.md
@@ -19,9 +19,11 @@
1. 검색 성능 향상
인덱스는 대체로 B+tree의 형태로 구성되기 때문에 데이터 조회 연산의 시간 복잡도를 $O(N)$에서 $O(\log{N})$으로 개선합니다.
+
2. 정렬 비용 감소
인덱스가 이미 정렬되어 있기 때문에 ORDER BY 절의 정렬 작업이 최적화됩니다.
+
3. join 연산 최적화
외래 키에 인덱스를 생성하는 경우 join 연산을 더 효율적으로 수행합니다. 검색 성능 향상의 연장선이라고도 볼 수 있는데, PK 값과 FK 값을 비교할 때 전체 데이터를 확인할 필요 없이 필요한 데이터만 검색하면 되므로 쿼리 성능이 높아지는 것입니다.
@@ -30,18 +32,569 @@
B Tree
- 
- 모든 리프 노드가 같은 레벨에 존재하고, 노드 내 데이터는 항상 정렬된 상태를 유지합니다.
- 모든 노드에 데이터를 저장할 수 있고, 리프 노드들이 서로 연결되어 있지 않습니다.
- 내부 노드는 데이터와 키를 함께 저장합니다.
- 노드의 데이터 수가 n개라면 자식 노드의 개수는 n+1개입니다.
+
+ - 모든 리프 노드가 같은 레벨에 존재하고, 노드 내 데이터는 항상 정렬된 상태를 유지합니다.
+ - 모든 노드에 데이터를 저장할 수 있고, 리프 노드들이 서로 연결되어 있지 않습니다.
+ - 내부 노드는 데이터와 키를 함께 저장합니다.
+ - 노드의 데이터 수가 n개라면 자식 노드의 개수는 n+1개입니다.
B+Tree
-
- 
- 리프 노드에만 데이터를 저장합니다.
- 리프 노드들은 연결 리스트로 연결되어 순차 접근이 용이합니다.
- 따라서, 내부 노드는 키 값만 저장하며 인덱스 역할만 수행합니다.
+
+
+ - 리프 노드에만 데이터를 저장합니다.
+ - 리프 노드들은 연결 리스트로 연결되어 순차 접근이 용이합니다.
+ - 따라서, 내부 노드는 키 값만 저장하며 인덱스 역할만 수행합니다.
+
+
+
+
+ Hash Table
+
+- 해시 함수를 사용하여 키를 해싱하고, 해시 테이블에 저장합니다.
+- 해시 테이블은 해시 값과 해당하는 데이터 레코드의 포인터를 저장합니다.
+- 검색 시 해시 값을 계산하여 해당하는 위치로 바로 이동하여 데이터를 찾을 수 있습니다. → 일반적으로 $O(1)$ 의 시간 복잡도를 가지게 됩니다.
+
+
+
+
+ B-Tree와 B+Tree 인덱스의 차이점을 설명하고, 각각 어떤 상황에서 더 효율적인지 설명해 주세요.
+
+B-Tree와 B+Tree의 주요 차이점은 데이터 저장 방식과 I/O 작업 방식의 차이가 있습니다. B-Tree는 모든 노드에 키와 데이터를 함께 저장하는 반면, B+Tree는 내부 노드에 키만 저장하고 실제 데이터는 리프 노드에만 저장합니다. 따라서 B-tree는 단일 레코드 검색이 주로 필요한 상황에서 유리하고, B+Tree는 범위 검색이 빈번한 곳에서 효율적입니다.
+
+B+Tree에서 단일 레코드 검색 시, 리프 노드까지 가야 하므로 B-Tree에 비해 느리고 B-Tree에서 범위 검색 시 시작점과 끝점의 페이지를 확인해야 해서 B+Tree에 비해 느립니다.
+
+
+
+ B-Tree와 Hash 인덱스의 차이점을 설명해주세요.
+
+해시테이블은 단일 행 접근은 빠를 수 있으나 key값이 달라지면 해시함수을 거쳐 value가 달라지기 때문에 다중 행 접근에 대해서 불가한 점이 있습니다.
+
+B-Tree는 단일 행 접근은 해시테이블보다 느릴지라도 다중 행 접근과 함께 사용할 수 있다는 장점이 있습니다.
+
+
+
+## 클러스터드 인덱스 vs 넌클러스터드 인덱스
+
+ 클러스터드 인덱스
+
+클러스터드 인덱스를 구성하기 위해서 행 데이터를 인덱스로 설정할 열로 정렬한 후에, 루트 페이지를 만들게 됩니다.
+즉, 물리적으로 행을 재배열 합니다.
+
+테이블 당 하나의 클러스터드 인덱스만 존재할 수 있습니다.
+
+클러드터드 인덱스 순서로 레코드들이 하드디스크에 저장됩니다. 클러스터드 인덱스를 따로 지정하지 않으면, 기본 키가 클러스터드 인덱스가 됩니다.
+즉, 테이블 생성 시 Primary Key(PK)를 지정하면, 그 컬럼은 자동으로 클러스터드 인덱스가 만들어집니다.
+
+
+
+ 넌클러스터드 인덱스
+
+레코드의 원본은 정렬하지 않고, 인덱스 페이지만 정렬됩니다. 넌클러스터드 인덱스는 데이터 페이지를 건드리지 않고, 별도의 장소에 인덱스 페이지를 생성합니다.
+
+인덱스 페이지의 리프 페이지에 인덱스로 구성한 열을 정렬 한 후 위치 포인터(RID)를 생성합니다. 즉, 넌클러스터드 인덱스의 인덱스 페이지(리프 페이지)는 키값과 데이터가 위치하는 포인터(RID)로 구성됩니다.
+
+넌클러스터드 인덱스는 여러 인덱스를 사용할 수 있어, 여러 연산에 최적화할 수 있는 유연성을 제공합니다.
+
+ > 포인터(RID): '파일그룹번호+데이터페이지 번호 + 페이지 내의 로우 번호'으로 구성되는 포인팅 정보입니다.
+
+
+
+ 클러스터드 인덱스와 넌클러스터드 인덱스의 차이는 무엇인가요?
+
+클러스터드 인덱스는 테이블의 실제 데이터를 인덱스 키값에 따라 물리적으로 정렬하고 저장하는 방식입니다.
+테이블 당 하나만 존재할 수 있으며, 주로 PK에 자동으로 생성됩니다.
+클러스터드 인덱스는 실제 데이터가 인덱스와 함께 저장되므로 검색 시 매우 빠릅니다.
+
+넌클러스터드 인덱스는 실제 데이터와 별도로 생성되며, 인덱스 키값과 실제 데이터를 찾아갈 수 있는 포인터를 저장합니다.
+한 테이블에 여러 개 생성할 수 있고, 인덱스 자체는 정렬되지만 실제 데이터는 물리적으로 재배열하지 않습니다.
+넌클러스터드 인덱스를 통한 조회는 넌클러스터드 인덱스에서 1번, 실제 데이터를 조회할 때 1번, 총 두번 디스크 접근이 있어 클러스터드 인덱스보다 느리지만, 자주 사용되는 검색 키나 정렬이 필요한 컬럼에 생성해 성능을 최적화할 수 있습니다.
+
+
+## 인덱스 적용시 고려사항
+
+ 어떤 컬럼에 인덱스를 적용해야 할까요?
+
+쿼리에서 자주 사용되는 컬럼을 대상으로 먼저 인덱스를 생성하고, 이 컬럼 중에, 선택도가 높은 컬럼을 위주로 인덱스를 생성합니다.
+복합 인덱스라면,
+1. 카디널리티가 높은 컬럼
+2. where 절에서 자주 사용되는 조건 유형:
+ - "=" 연산자로 사용되는 컬럼
+ - 범위 검색에 사용되는 컬럼 (BETWEEN, >, < 등)
+3. ORDER BY에 사용되는 컬럼
+4. GROUP BY에 사용되는 컬럼
+
+순으로 컬럼 순을 배치합니다. 이는 B-Tree의 탐색 특성 때문에, 선행 컬럼의 조건이 명확할 수록 인덱스 효율이 높아지기 때문입니다.
+
+쓰기 작업이 많은 테이블에는 인덱스 사용을 자제해야 합니다. 한번 쓰기 작업을 하면 인덱스도 변경해야 하는 오버헤드가 추가로 발생하기 때문입니다.
+
+복합 인덱스의 경우 꼭 같이 나와야 하는 컬럼을 묶어주면 성능 개선에 좋습니다.
+> 선택도: 전체 데이터에서 특정 조건에 의해 선택되는 데이터의 비율
+> 카디널리티: 컬럼 내 중복되지 않은 고유값의 수
+
+
+
+
+
+ 쿼리 실행 계획과 인덱스의 관계
+쿼리 실행 계획은 데이터베이스가 쿼리를 처리하는 방법을 보여주며, 어떤 인덱스를 사용할지 결정합니다. 실행 계획을 분석하면 인덱스 사용 여부와 효율성을 확인할 수 있습니다.
+
+인덱스 성능은 쿼리 실행 계획, 성능 모니터링 도구, 벤치마크 테스트 등을 통해 분석할 수 있습니다. 인덱스 추가 전후의 쿼리 성능을 비교하여 효과를 측정할 수 있습니다.
+
+
+## 인덱스로 인해 성능이 낮아지는 경우
+
+ 실행 시간 관점
+너무 많은 인덱스는 추가 저장 공간을 필요로 하고, 데이터 수정 작업(`INSERT, UPDATE, DELETE`)의 성능을 저하시킵니다. 또한 데이터베이스의 백업 및 복원 작업도 느려질 수 있습니다.
+
+테이블의 데이터가 적은 경우 (레코드 수: 100 ~ 9999)에서는 전체 테이블 스캔이 더 효율적일 수 있습니다. 인덱스를 통한 조회는 실제 데이터에 접근하는데 두 단계 작업이 필요하기 때문입니다. 중복 값이 많은 컬럼에 인덱스를 생성하면 옵티마이저가 인덱스를 사용하더라도 많은 양의 데이터를 스캔해야 하므로 성능 이점이 없거나 오히려 저하될 수 있습니다.
+
+
+
+
+
+ 메모리적 관점
+사용하지 않는 인덱스도 계속 유지되며, 데이터 변경 작업마다 업데이트됩니다. 이로 인해 메모리와 디스크 공간이 낭비되고, 데이터 수정 작업 시 불필요한 오버헤드가 발생합니다.
+
+
+# 정규화, 역정규화
+## 정규화
+
+ 정규화란?
+
+데이터베이스 설계 과정에서 데이터의 정확성과 일관성을 유지하기 위해 데이터를 구조화하는 방법입니다. 테이블을 작은 단위로 분해하며 데이터 중복, 삽입, 삭제, 갱신 이상 현상을 방지합니다. 데이터 쓰기 성능은 향상되나 조회 성능은 처리 조건에 따라 향상될 수도, 저하될 수도 있습니다. 정규화는 제1정규형부터 제5정규형까지 단계적으로 진행되며, 실무에서는 주로 제3정규형이나 BCNF까지 적용합니다.
+
+
+
+ 정규화를 왜 사용할까요?
+
+1. 데이터 중복 제거
+ 정규화는 데이터 중복을 최소화하기 때문에 중복된 데이터의 수정, 누락 등의 문제가 발생하지 않습니다.
+ 데이터 불일치를 막을 수 있습니다.
+
+
+2. 데이터 일관성 유지
+ 정규화를 진행하는 경우 외래키를 통해 다른 테이블의 정보를 참조하므로 한 곳에서 데이터를 수정하는 경우 다른 테이블에서도 수정된 데이터에 접근이 가능합니다.
+
+
+3. 데이터 이상 방지
+ 정규화는 삽입, 삭제, 갱신 이상 현상을 방지합니다.
+
+
+4. 공간 효율성 향상
+ 데이터 중복을 제거함으로써 저장 공간을 효율적으로 사용할 수 있습니다. 같은 데이터를 여러 번 저장하지 않기 때문에 데이터베이스 크기가 줄어들고, 이는 특히 대규모 시스템에서 상당한 공간 절약으로 이어집니다.
+
+
+
+### 1NF, 2NF, 3NF, BCNF
+
+ 1NF란?
+
+정규화의 첫 단계로, 테이블의 각 속성(컬럼)은 원자값(Atomic)을 가져야 한다는 규칙입니다. 즉, 테이블의 모든 속성이 더 이상 분해할 수 없는 단일 값을 가져야 합니다.
+
+특징:
+- 각 컬럼은 하나의 값만 가져야 함
+- 반복되는 그룹이 없어야 함
+- 모든 레코드는 유일한 기본키를 가져야 함
+
+
+
+ 2NF란?
+
+1NF의 모든 조건을 만족하면서 부분적 함수 종속성을 제거한 형태입니다. 테이블의 모든 일반 속성은 기본키 전체에 종속되어야 하며, 기본키의 일부에만 종속되면 안된다는 의미입니다.
+
+예를 들어, 주문번호, 제품 ID, 제품명, 수량, 가격 컬럼이 있고 기본키는 (주문번호 + 제품 ID)라 하겠습니다. 제품명은 PK 중 제품 ID에만 종속됩니다. 모든 PK에 종속되는 것이 아니기 때문에 2NF를 위반하는 상황입니다. 이를 해결하기 위해서 제품 ID가 기본키인 제품 테이블을 따로 생성하여 주문과 제품 테이블을 분리해야 합니다.
+
+### 위반하는 테이블 (주문 테이블)
+| 주문번호 | 제품ID | 제품명 | 수량 | 가격 |
+|---------|-------|-------|------|------|
+| 1001 | P001 | 노트북 | 1 | 1,200,000 |
+| 1001 | P002 | 마우스 | 2 | 30,000 |
+| 1002 | P001 | 노트북 | 1 | 1,200,000 |
+| 1003 | P003 | 키보드 | 1 | 50,000 |
+
+### 2NF로 개선한 테이블
+
+**주문 테이블**
+
+| 주문번호 | 제품ID | 수량 | 가격 |
+|---------|-------|------|------|
+| 1001 | P001 | 1 | 1,200,000 |
+| 1001 | P002 | 2 | 30,000 |
+| 1002 | P001 | 1 | 1,200,000 |
+| 1003 | P003 | 1 | 50,000 |
+
+**제품 테이블**
+
+| 제품ID | 제품명 |
+|-------|-------|
+| P001 | 노트북 |
+| P002 | 마우스 |
+| P003 | 키보드 |
+
+
+
+ 3NF란?
+
+제2정규형의 모든 조건을 만족하면서 이행적 함수 종속성을 제거한 형태입니다. 기본키가 아닌 속성들은 기본키에만 의존해아 하며, 다른 일반 속성에 의존하면 안된다는 것입니다.
+
+예를 들어, 학번, 이름, 학과, 학과 전화번호 컬럼을 가지는 테이블이 있다고 가정하겠습니다. 학과는 학번에 종속되고, 학과 전화번호는 학과에 종속됩니다. 즉, 학과 전화번호는 이행적으로 종속됩니다. 이 때, 학생 정보 테이블과 학과 테이블 이름을 분리하는 것이 3NF입니다.
+
+### 위반하는 테이블 (학생 테이블)
+
+| 학번 | 이름 | 학과 | 학과 전화번호 |
+|------|------|------|--------------|
+| 20201 | 김철수 | 컴퓨터공학과 | 02-1234-5678 |
+| 20202 | 이영희 | 컴퓨터공학과 | 02-1234-5678 |
+| 20203 | 박지민 | 경영학과 | 02-9876-5432 |
+| 20204 | 정민수 | 경영학과 | 02-9876-5432 |
+
+### 3NF로 개선한 테이블
+
+**학생 테이블**
+
+| 학번 | 이름 | 학과코드 |
+|------|------|---------|
+| 20201 | 김철수 | CS001 |
+| 20202 | 이영희 | CS001 |
+| 20203 | 박지민 | BZ001 |
+| 20204 | 정민수 | BZ001 |
+
+**학과 테이블**
+
+| 학과코드 | 학과명 | 학과 전화번호 |
+|---------|-------|--------------|
+| CS001 | 컴퓨터공학과 | 02-1234-5678 |
+| BZ001 | 경영학과 | 02-9876-5432 |
+
+
+
+ BCNF란?
+
+3NF를 강화한 형태로 모든 결정자가 후보키가 되도록 합니다. 3NF는 기본키가 아닌 속성이 다른 후보키가 아닌 속성을 결정하는 경우를 허락하나, BCNF는 모든 결정자가 반드시 후보 키여야 합니다. 3NF에서는 일반 속성 간의 종속 관계만 살펴보지만, BCNF의 경우 결정자가 후보 키가 아닌 경우 무조건 위배되는 것으로 판단합니다.
+
+### 함수 종속성과 정규형 만족 여부
+
+| 함수 종속 | 후보 키 여부 | 제3정규형 만족 여부 | BCNF 만족 여부 |
+|----------|------------|------------------|---------------|
+| 후보키 → 일반 속성 | ✅ | ✅ | ✅ |
+| 일반 속성 → 일반 속성 | ❌ | ❌ | ❌ |
+| 일반 속성 → 후보키 일부 | ❌ | ✅ | ❌ |
+| 일반 속성 → 후보키 전체 | ❌ | ✅ | ❌ |
+
+### 예시: BCNF 위반 테이블
+
+**수강 테이블**
+
+| 학번 | 과목코드 | 교수 | 강의실 |
+|------|---------|------|-------|
+| S001 | C001 | 김교수 | 301호 |
+| S002 | C001 | 김교수 | 301호 |
+| S001 | C002 | 박교수 | 302호 |
+| S003 | C002 | 박교수 | 302호 |
+| S002 | C003 | 이교수 | 303호 |
+
+위 테이블에서:
+- 기본키/후보키: (학번, 과목코드)
+- 함수 종속성:
+ * (학번, 과목코드) → 교수, 강의실
+ * 과목코드 → 교수
+
+과목코드만으로 교수를 결정할 수 있으나, 과목코드는 후보키(학번, 과목코드)의 일부입니다. 이 경우 일반속성 간 종속성이 없으나 일반속성(과목코드)이 후보키의 일부에 종속되므로 제3정규형은 만족하지만 BCNF는 위반합니다.
+
+### BCNF로 개선한 테이블
+
+**과목_교수 테이블**
+
+| 과목코드 | 교수 |
+|---------|------|
+| C001 | 김교수 |
+| C002 | 박교수 |
+| C003 | 이교수 |
+
+**수강_강의실 테이블**
+
+| 학번 | 과목코드 | 강의실 |
+|------|---------|-------|
+| S001 | C001 | 301호 |
+| S002 | C001 | 301호 |
+| S001 | C002 | 302호 |
+| S003 | C002 | 302호 |
+| S002 | C003 | 303호 |
+
+
+
+### 정규화의 장단점
+
+
+ 장점
+
+- 스토리지 효율성 향상
+ 중복 데이터 제거로 저장 공간이 절약됩니다. 뿐만 아니라 작은 테이블은 큰 테이블과 비교했을 때 메모리에 더 효율적으로 캐싱됩니다.
+
+
+- 쓰기 작업 최적화
+ 데이터가 중복되지 않아 하나의 데이터만 수정하면 되기 때문에 업데이트가 빠르고 효율적입니다. 테이블이 저장하는 데이터의 양이 많지 않아 삽입, 삭제 시에도 불필요한 데이터를 저장하거나 삭제하는 과정이 줄어듭니다.
+
+
+
+ 단점
+
+- 조인 증가로 인한 오버헤드
+ 여러 테이블로 분산된 데이터를 가져오기 위해서는 조인이 필요합니다. 정규화가 지나친 경우, 조인 연산이 복잡해져 쿼리 성능이 저하될 수 있습니다. 또한 여러 테이블에 접근해야 하기 때문에 디스크 I/O 작업이 증가합니다.
+
+
+
+## 역정규화
+
+ 역정규화가 필요한 이유에 대해 설명하세요.
+
+역정규화는 다음과 같은 상황에 필요합니다.
+1. 조회 성능이 중요하거나 조회 작업이 압도적으로 많은 테이블
+2. 조인이 많은 테이블
+3. 응답 시간이 중요한 서비스(데이터 무결성보다 성능이 우선시 되는 경우)
+4. 테이블이 너무 많아 유지보수 하기 어려운 상황
+5. OLAP(Online Analytical Processing)
+ - OLAP: 대규모 데이터를 다차원적으로 분석하기 위한 데이터베이스, 다차원 데이터 모델을 사용해 복잡한 쿼리와 집계 연산을 효율적으로 처리하며, 대용량 데이터를 분석
+
+
+### 역정규화의 장단점
+
+
+ 장점
+
+- 읽기 작업 성능 향상
+ 여러 테이블의 데이터를 하나의 테이블에 통합하여 저장하기 때문에 조인 연산이 감소합니다. 이는 읽기 중심 서비스에서 큰 강점을 가집니다.
+
+
+- I/O 작업 감소
+ 하나의 테이블만 접근하기 때문에 I/O 비용이 감소합니다. 즉, 관련된 데이터가 함께 저장되기 때문에 디스크 캐싱 효율성이 증가합니다.
+
+
+
+ 단점
+
+- 데이터 무결성 위험 증가
+ 중복 데이터로 인해 일관성 문제가 생길 수 있습니다. 같은 데이터가 여러 곳에 중복되어 저장되는 상황에서 업데이트를 진행하는 경우, 모든 데이터를 업데이트하지 않으면 데이터 불일치가 발생합니다. 뿐만 아니라 쓰기 작업 진행 시 데이터 이상 현상 발생 가능성이 높아집니다.
+
+- 데이터 저장 공간 증가
+ 같은 데이터가 여러 곳에 저장되어 전체 데이터베이스의 크기가 증가할 수 있습니다. 큰 데이터베이스는 백업과 복구에 더 많은 시간과 자원을 필요로 한다는 문제도 존재합니다.
+
+
+
+
+📌 **결론**: 정규화는 데이터 일관성과 무결성이 최우선인 시스템(금융, 의료)이나 쓰기 작업이 자주 발생하는 시스템에서, 역정규화는 읽기 작업이 대부분인 시스템, 데이터 변경이 상대적으로 적은 시스템 등에서 적합합니다.
+
+
+## 실무에서의 정규화 역정규화
+
+
+ 좋아요 테이블과 게시판 테이블
+
+
+- posts 테이블은 현재 1:N 관계로 likes 테이블과 조인 관계에 있습니다.
+ 이때, posts 테이블에 "좋아요" 컬럼을 넣어 주는게 좋을까요? 아니면 정규화의 관점에서 중복이 되니까 "좋아요 수"는 안 넣는게 좋을까요?
+
+ - 하나의 posts 테이블의 경우, 매우 많은 "좋아요"를 가지고 있습니다. 따라서 "좋아요" 컬럼이 없다면 1:N 관계에서 조인을 이용해 모든 정보를 가져와야 하고, 이는 조인의 비용이 매우 클 것입니다.
+ - 따라서, 이 경우에는 posts 테이블에 "좋아요 수" 컬럼을 넣고, "좋아요"가 추가될 때마다 posts의 "좋아요 수"를 업데이트해서 정합성을 지키는게 좋은 방법이 될 것입니다.
+
+
+
+
+# 트랜잭션
+## 트랜잭션
+
+
+ 트랜잭션이란?
+
+데이터베이스의 상태를 변화시키는 하나의 논리적 작업 단위입니다. 즉, 여러 개의 작업이 모두 성공하거나 하나라도 실패하면 전부 실패하도록 처리되는 연산 묶음입니다.
+
+
+
+ 트랜잭션의 상태
+
+
+1. 활성화 `Active`
+ 트랜잭션이 시작되어 연산을 수행 중인 상태입니다. 아직 `commite`이나 `rollback`되지 않은 상태입니다.
+
+
+2. 부분 완료 `Partically Committed`
+ 마지막 연산이 실행된 후 `commit`명령을 기다리는 단계로 트랜잭션의 결과를 데이터베이스에 반영하기 전 단계입니다. 부분 완료 상태는 DBMS 내부 구현 수준의 개념으로, 프레임워크 수준에는 직접 노출되지 않습니다.
+
+
+3. 완료 `committed`
+ 트랜잭션이 성공적으로 완료되어 데이터베이스에 변경사항이 반영된 상태입니다. `committed`이 완료되는 시점은 지속성이 보장되는 시점입니다.
+
+
+4. 실패 `failed`
+ 트랜잭션 실행 중 오류가 발생하여 정상적으로 완료하지 못한 상태입니다. 제약조건 위반이나 시스템 오류등에 의해 발생합니다. 이 상태에서는 변경된 작업이 적용되지 않아야 하기 때문에 `rollback`을 진행합니다.
+
+
+5. 철회 `aborted`
+ 트랜잭션이 실패하여 모든 변경 내용이 취소된 상태입니다. 데이터베이스는 트랜잭션 이전 상태로 복구되며, 재시도 로직이 있는 경우 재시도될 수 있고 그렇지 않으면 완전히 종료됩니다.
+
+
+
+ 트랜잭션의 성질(ACID)
+
+ACID는 Atomicity, Consistency, Isolation, Durability로 데이터의 정합성과 일관성을 보장하는 트랜잭션의 성질입니다.
+- Atomicity(원자성)은 트랜잭션의 모든 연산이 완전히 수행되거나 전혀 수행되지 않아야 한다는 것입니다. 즉, 트랜잭션 내의 모든 작업 중 부분적 실행이 불가능하며 하나의 트랜잭션은 `commit`이나 `rollback` 중 무조건 하나를 선택해야 합니다.
+- Consistency(일관성)은 데이터베이스의 모든 제약조건과 규칙이 트랜잭션 전후로 유지되어야 하는 것입니다.
+- Isolation(격리성)은 트랜잭션 간의 데이터 접근을 서로 격리하여, 서로 영향을 미치지 않도록 하는 것을 의미합니다.
+- Durability(지속성)은 한 번 커밋된 데이터는 어떤 일이 있어도 유실되서는 안되고 지속되어야 한다는 의미입니다.
+
+
+## 격리 수준
+
+트랜잭션의 격리수준은 크게 `Read Uncommited` `Read commited` `Repeatable read` `Serializable` 으로 나뉘며 뒤로 갈수록 엄격해집니다.
+
+
+ Read Uncommitted
+
+READ UNCOMMITTED는 커밋이 되지 않은 트랜젹션의 데이터 변경 내용을 다른 트랜잭션이 조회하는 것을 허용하는 격리수준입니다. read uncommitted는 같은 트랜잭션 내에서 같은 쿼리를 여러 번 실행했을 때 다른 결과가 나올 수 있어 데이터 일관성이 깨집니다. Dirty Read, Non-repeatable Read, Phantom Read 문제가 발생할 수 있습니다.
+
+
+
+ Read committed
+
+Read committed는 커밋된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회할 수 있는 격리 수준입니다. 특정 트랜잭션이 수행되는 동안 다른 트랜잭션은 현재 커밋된 데이터 스냅샷을 읽습니다. Dirty Read는 해결했지만, Non-repeatable Read와 Phantom Read는 발생할 수 있습니다.
+
+
+
+ Repeatable read
+
+한 트랜잭션이 특정 레코드를 조회할 때 하나의 행에서 정보를 가져올 때 동일한 응답임을 보장합니다.
+
+- `Repeatable Read`에서는 한 트랜잭션이 동일한 행(row)을 반복 조회할 때 항상 같은 결과를 보장하여 Non-Repeatable Read를 방지합니다.
+- 하지만, 일반적으로 동일한 조건으로 조회하는 결과 집합 전체에 대한 일관성은 보장하지 않으므로 Phantom Read는 방지하지 못합니다.
+- 그러나 MySQL의 InnoDB 스토리지 엔진은 MVCC 기반의 Undo 로그를 활용하여 트랜잭션 시작 시점의 스냅샷을 기준으로 조회하기 때문에, 실질적으로 Phantom Read까지 방지됩니다.
+
+
+
+ Serializable
+
+완전히 트랜잭션을 사용하는 테이블이라면, 다른 트랜잭션이 접근할 수 없도록 만드는 것입니다.
+
+- 이를 통해서 모든 문제점들을 해결할 수 있습니다.
+- 참고
+
+참고로 mysql의 기본 격리 수준은 아래와 같이 Repeatable-read입니다.
+
+
+
+
+
+## 낮은 격리 수준시 발생하는 현상
+
+
+ 더티 리드 `Dirty Read`
+
+한 트랜잭션이 아직 커밋되지 않은 다른 트랜잭션의 변경사항을 읽는 현상입니다. 커밋되지 않은 데이터는 나중에 롤백 될 수 있습니다. 롤백된 경우 잘못된 데이터를 기반으로 한 연산이 발생하기 때문에 문제가 됩니다.
+
+
+
+ 반복 불가능한 읽기 `Non-repeatable Read`
+
+한 트랜잭션 내에서 같은 쿼리를 두 번 실행했을 때 다른 결과가 나오는 현상입니다. 두 쿼리가 실행되는 중간에 다른 트랜잭션이 데이터를 수정한 경우 발생됩니다.
+
+
+
+ 팬텀 리드 `Phantom Read`
+
+한 트랜잭션 내에서 같은 쿼리를 두 번 실행했을 때, 첫 번째 쿼리와 두 번째 쿼리의 결과 행 수가 달라진 경우입니다.
+
+
+
+ 갱신 손실 `Lost Update`
+
+서로 다른 트랜잭션이 같은 데이터를 동시에 업데이트할 때, 한 트랜잭션의 변경사항이 다른 트랜잭션에 의해 덮어쓰여지는 현상입니다.
+
+
+
+ 트랜잭션 병행 제어기법 대표적인 두 가지
+
+1. 락킹(Locking) : 트랜잭션이 데이터에 접근할 때 동시에 접근하지 못하도록 락을 설정하고,
+ 트랜잭션은 Lock을 획득한 뒤에만 연산 가능합니다
+ - 2단계 락킹 프로토콜
+ - 확장 단계 : Lock만 수행 가능하고, 더이상 Unlock은 수행 불가합니다.
+ - 축소 단계 : Unlock만 수행 가능하고, 더 이상 Lock은 수행 불가합니다.
+
+ 이렇게 단계를 나누어 프로토콜을 정한 이유 는 직렬 가능성 (serializablity) 확보를 위함입니다.
+
+ 1. S-Locking (공유잠금)
+ - 공유잠금을 설정한 트랜잭션은 데이터 항목에 대해 읽기 연산만 가능합니다.
+ - 하나의 데이터 항목에 대해 여러 개의 공유잠금이 가능합니다.
+ - 다른 트랜잭션도 읽기 연산만을 실행 할 수 있습니다.
+ 2. X-Locking (배타잠금)
+ - 배타잠금을 설정한 트랜잭션은 데이터 항목에 대해 읽기 연산(read)과 쓰기 연산(write) 모두 가능합니다.
+ - 하나의 데이터 항목에 대해서 하나의 배타잠금만 가능합니다.
+ - 다른 트랜잭션은 읽기연산과 쓰기연산 둘 다 불가능합니다.
+2. 타임스탬프 : 각 트랜잭션에 고유한 타임스탬프를 부여해서 시간 순서대로 연산을 수행하도록 제어하는 방식입니다.
+ - 각 데이터에 읽은 시간, 쓴 시간이 저장되어 있습니다.
+ - 데이터를 읽거나 쓸 때 자신보다 미래시간에 접근된 기록이 있다면 충돌로 간주하고 롤백합니다.
+ - 장단점
+ - 장점 : 교착상태(deadlock)가 발생하지 않습니다.
+ - 단점 : 복귀가 반복되어 성능이 저하될 수 있습니다.
+
+
+
+## Mysql에서 Undo 로그와 Redo로그
+
+ undo,redo
+
+- Redo로그는 변경 쿼리(update,insert,Delete)연산을 수행한 후에 저장되고, Undo 로그는 변경 쿼리연산의 수행 전에 저장됩니다.
+- Undo로그는 변경 쿼리 연산 수행전에 저장해서, 해당 연산에서 예외가 발생 시 롤백 될때 참고하는 용으로 저장되고, Redo의 경우 커밋되었으나, 버퍼에만 반영되고, 아직 디스크에 변경이 되지 않았는데, 장애가 일어났을 때 복구를 위해서 사용합니다.
+- Mysql은 성능을 위해서 매번 디스크에 접근하는게 아닌 특정 시점에서만 디스크에 저장하기에 redo 로그가 필요합니다.
+
+
+
+ 코드
+
+```
+-- 트랜잭션 A 시작 (트랜잭션 ID = 100)
+START TRANSACTION;
+
+SELECT * FROM user WHERE id = 1;
+-- user(id=1)의 버전 1 (트랜잭션 90에서 커밋한 값)을 읽음
+
+-- 트랜잭션 B가 user(id=1)를 업데이트하고 커밋 (트랜잭션 ID = 101)
+UPDATE user SET name = 'Bob' WHERE id = 1;
+COMMIT;
+
+-- 트랜잭션 A에서 다시 같은 SELECT 실행
+SELECT * FROM user WHERE id = 1;
+-- 여전히 버전 1을 읽음. 왜?
+-- InnoDB는 Undo 로그를 따라가서 트랜잭션 100보다 이전에 커밋된 버전(트랜잭션 90)을 찾기 때문.
+
+```
+- MVCC는 읽기 일관성을 유지하기 위해, 트랜잭션 시점에 따라 필요한 레코드의 undo 로그를 따라가며
+과거 버전을 조회합니다.
+
+
+## @Transactional(readOnly = true)
+
+ readonly의 이점
+
+- 기본적으로 일반 @Transactional의 경우 Dirty check를 통해서persistcontext에서 엔티티가 변경되었는지를 확인하는데 이 로직을 생략하기에 성능상 이점을 가지고 있습니다.
+- 또한 플러시도 되지 않기때문에 성능상 이점을 가지게 됩니다. (디스크에 접근을 줄이므로)
+
+
+## 트랜잭션의 단위
+
+ 메서드 단위
+
+기본적으로 하나의 트랜잭션은 하나의 서비스 로직 즉 메서드 단위로 묶는게 일반적입니다.
+이는 트랜잭션의 범위를 명확히 하여 데이터 정합성을 보장하고, 예외 발생 시 일관된 롤백 처리를 가능하게 하기 위함입니다.
+
+
+## 자바,스프링 환경에서 트랜잭션을 처리할 때 주의 해야 할 점
+
+ 프록시 형태의 @Transactional
+
+- A) 대표적으로 private메서드에서 @Transactional이 적용되지 않는 것이 있습니다.
+- Spring AOP는 기본적으로 public, protected메서드에서만 적용됩니다.
+ - 프록시 객체에서 실제 객체를 호출해야 하기 때문입니다.
+- 또한 같은 내부 클래스에서 호출하는 경우 @Transactional은 적용이 되지 않으므로 주의가 필요합니다.
+ - 프록시 객체가 아닌 내부 클래스에서 this를 통해서 직접 호출하기 때문입니다.
\ No newline at end of file
diff --git a/Computer Science/Database/image/B+Tree.png b/Computer Science/Database/image/B__Tree.png
similarity index 100%
rename from Computer Science/Database/image/B+Tree.png
rename to Computer Science/Database/image/B__Tree.png
diff --git a/Computer Science/Database/image/liketable_boardtable.png b/Computer Science/Database/image/liketable_boardtable.png
new file mode 100644
index 0000000..ec56955
Binary files /dev/null and b/Computer Science/Database/image/liketable_boardtable.png differ
diff --git a/Computer Science/Database/image/repeatable-read result.png b/Computer Science/Database/image/repeatable-read result.png
new file mode 100644
index 0000000..a606fc4
Binary files /dev/null and b/Computer Science/Database/image/repeatable-read result.png differ
diff --git a/Computer Science/Database/image/transactionStatus.png b/Computer Science/Database/image/transactionStatus.png
new file mode 100644
index 0000000..bcc1b2f
Binary files /dev/null and b/Computer Science/Database/image/transactionStatus.png differ
diff --git a/README.md b/README.md
index a89af2f..8989ec6 100644
--- a/README.md
+++ b/README.md
@@ -39,18 +39,18 @@ CS의 바이블은 웹 개발 분야의 기술, CS 지식을 기반으로 **면
## 📅 스터디 진행 일정표
-| 날짜 | 주제 |
-|------------|------|
-| 4월 2일 | 인덱스, 정규화, 역정규화, 트랜잭션 |
+| 날짜 | 주제 |
+|------------|------------------------------------------------------|
+| 4월 2일 | 인덱스, 정규화, 역정규화, 트랜잭션 |
| 4월 9일 | 파티셔닝, 교착상태, RDB, NoSQL, Statement, PreparedStatement |
-| 4월 16일 | |
-| 4월 23일 | |
-| 4월 30일 | |
-| 5월 7일 | |
-| 5월 14일 | |
-| 5월 21일 | |
-| 5월 28일 | |
-| 6월 4일 | |
+| 4월 16일 | 휴식 |
+| 4월 23일 | REST, HTTP & HTTPS, DNS, 세션, 쿠키, JWT, OAuth2.0 |
+| 4월 30일 | WEB SERVER & WAS, 서버 사이드 렌더링, 클라이언트 사이드 렌더링, 캐싱 |
+| 5월 7일 |CORS, CSRF, 리버스 프록시, 프론트 프록시, 로드밸런싱|
+| 5월 14일 | |
+| 5월 21일 | |
+| 5월 28일 | |
+| 6월 4일 | |
## 📂 주제별 목록
### Database
@@ -73,4 +73,28 @@ CS의 바이블은 웹 개발 분야의 기술, CS 지식을 기반으로 **면
- Statement
- PreparedStatement
+### Web
+
+#### 📌 통신과 프로토콜
+- REST
+- HTTP & HTTPS
+- DNS
+
+#### 📌 인증과 권한
+- 세션
+- 쿠키
+- JWT
+- OAuth 2.0
+
+#### 📌 웹 서버 아키텍처
+- WEB SERVER & WAS
+- 서버 사이드 렌더링
+- 클라이언트 사이드 렌더링
+
+#### 📌 보안과 성능
+- CORS
+- CSRF
+- 리버스 프록시
+- 프론트 프록시
+- 로드밸런싱