Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[수진] 8-9장 #24

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions 08장/8장_조수진.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# 8장. 테이블 설계의 기초 - 테이블의 개념과 정규형

테이블은 공통 요소들의 집합이며, 함수이다.(X를 입력하면 Y를 출력하는 대응표)

### 테이블 설계의 기초

관계형 데이터베이스에서 데이터는 테이블에 저장된다. 대규모의 복잡한 데이터를 모순없이 장기적으로 관리하기 위해 테이블 설계가 중요하다.

테이블은 `어떤 공통 속성을 가진 집합(개념)` 이며, 표의 형식을 가진다.

→ 테이블 명은 반드시 복수형이나 집합명사로 표현해야 한다.

시스템에서 하드웨어어와 관련있는가로 구분지어,
아키텍처 설계 = 물리 설계
테이블 설계 = 논리 설계

### 테이블 설계 규칙

1. 사물과 사물의 집합은 계층이 다르다

예시) 완두콩 테이블, 토마토 테이블, 옥수수 테이블 X → 채소 테이블

예시) 토마토 테이블(O) → 토마토A, 토마토B, 토마C..

2. 가장 상위의 개념 집합으로 정리한다

: 문맥에 따라 규정하는 집합이 달라질 수 있다

예시) 회원 테이블(O), 일반 회원 & 프리미엄 회원 테이블(O), 남성 회원 & 여성 회원 테이블(O)..

→ 가장 상위의 회원을 테이블로 만들고, 일반&프리미엄 회원, 성별은 열로 구별한다

→ 이렇게 했을 때, 애플리케이션의 유연성이 높아진다

3. 열이란 개체의 속성이다

RDB를 자바에 맵핑하면 테이블은 클래스, 행은 인스턴스, 열은 속성에 해당

4. 현실 세계에 같은 사람은 2명 있지 않다

→ 한 개의 테이블의 내용에는 중복 행이 있다면 실제 두 데이터의 구분이 지 않는다 → 허용하지 않는다

5. 기본키 할당은 관리의 기본

→ 데이터를 고유하게 식별할 수 있는 기본키를 반드시 할당하라(ex. 회원 ID, 건강보험증 번호 등)

6. 기본키는 중복되면 안된다
7. 기본키의 값이 바뀌면 왜 곤란한가
- 변경 후 값의 유일성을 보증할 수 없다
- 과거 데이터와의 결합(매칭)이 어렵다
8. 기본키 열로 Null 불가

### 정규형

정규형 = 제대로 된 형태 = 데이터의 갱신이 발생한 경우에도 부정합이 발생하기 어려운 테이블의 형태

제1-5정규형이 있지만 실무에서는 정합성을 유지하기 위해 주로 `제2,3정규형`을 이해하는 것이 중요!

**함수 종속성(Functional Dependency)**

테이블은 Y = F(X)의 관계를 맺는 입력값과 출력값의 대응표이다

→ 기본키 열(X)와 일반키 열(Y) 사이에 성립하는 함수적인 유일성을 함수 종속성. 중괄호로 표현.

`{사원 ID} → {이름, 나이}`

**제1정규형(1NF)**

테이블 셀에 복합적인 값(배열, 복수의 값)을 포함하지 않는다

= 스칼라 값(단일값, 더 이상 나눠지지 않는 값) 이외의 값을 포함하지 않는다

- 복합키를 허용하면 기본키가 행의 값(일반키의 열)을 고유하게 특정할 수 없기 때문

**제2정규형(2NF)**

부분 함수 종속성(기본키를 구성하는 열의 일부에만 함수 종속이 존재하는 것)을 가지지 않는다

→ 기본키: {주문번호 + 상품코드} But {상품코드} → {상품명}

⇒ 집합을 더 명확하게 분리시킨다

![Untitled](https://lxxjn0-dev.netlify.app/static/8a27ce35b98f16356d07f35214c5d397/7d769/regular-3.png)

- 제2정규화가 되지 않으면,
- 테이블의 부분 정보를 알지 못하면 데이터를 등록하기 어렵다
- 부분 함수 종속에 해당하는 부분이 중복되며, 일부가 잘못 등록될 수 있다 = 데이터 부정합 = 갱신 이상

**제3정규형(3NF)**

추이함수 종속(기본키 이외의 키 간에 발생하는 함수 종속)을 가지지 않는다

⇒ 추이 함수 종속이 생기는 부분을 테이블 분리(집합을 명확히 분리)

![Untitled](https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9974AB4E5BD9AB0A1E)

- 제3정규화가 되지 않으면, 아직 관계가 생기지 않은 데이터를 등록(ex. 기계공학과)할 방법이 없다

### ER 다이어그램

테이블의 수가 많아지면 테이블 간의 관계성을 파악하기 어렵다. 이런 테이블 간의 관련선을 한눈에 알 수 있게 그래픽으로 표현하는 기술이 ER 다이어그램

![Untitled](https://blog.kakaocdn.net/dn/4AmaB/btqEP3qzzcU/TLPnBeceKcKJ2g7Ylib5Dk/img.png)

- 엔티티는 사각형으로 표현
- 엔티티 윗 부분은 기본키
- 엔티티 아래 기타 열 표기
- FK는 외래키
- 외래키에 의한 엔티티간의 관계(릴레이션십)은 기호로 표현
- 점선: 참조하는 엔티티는 참조되는 엔티티(부모 개체)의 존재여부와 관계없이 존재할 수 있음
- 직선: 참조하는 엔티티는 참조되는 엔티티(부모 개체)가 존재해야 존재할 수 있음

→ 부모 개체의 키가 주식별자인 경우

- O: 0
- -: 1
- 새다리 모양: 2이상(복수)
Empty file removed 08장/empty.txt
Empty file.
93 changes: 93 additions & 0 deletions 09장/9장_조수진.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# 9장. 백업과 복구 - 장애에 대비하는 구조

### 지속성과 성능이 양립하는 구조

트랜잭션의 ACID성질 중 Durability에 의해 한 번 반영(commit)된 동작은 영속화된다. 정상적인 동작 시 뿐만아니라 데이터베이스 서버나 OS의 비정상적인 종료 등 시스템 장애에서도 유지된다. 보존되는 데이터는 대부분 하드디스크에 저장된는데, 동기화 쓰기를 하면 성능에 부정적이기 때문에 로그 선행 쓰기(WAL 로그), 데이터베이스 버퍼 구조를 이용해 데이터베이스 파일에 동기화한다.

**로그 선행 쓰기 - WAL(write ahead log)**

변경에 대한 로그 레코드를 이용해서 동기화한다

MySQL에서는 InnoDB 로그라고 부른다

- 디스크에 연속해서 쓰기 때문에 무작위로 쓰는 것보다 성능이 좋다
- 디스크에 쓰는 용량과 횟수를 줄일 수 있다
- 데이터베이스 버퍼를 이용해 데이터베이스의 데이터 파일로의 변경을 효율성 높게 수행한다

**데이터베이스 버퍼**

WAL에 변경을 작성하기 때문에 트랜잭션 커밋마다 동기화 할 필요가 없다. 하지만 계속해서 비동기적인 쓰기를 하면 로그와 데이터 파일 간 일관성을 유지하기 어렵다

→ 데이터 파일로의 입력을 데이터베이스 버퍼 경유로 일원화해서 단순화

→ 효율적으로 데이터의 일관성 유지 가능

**MySQL 갱신 흐름**

1. 갱신 대상 데이터를 포함한 페이지가 버퍼 풀에 있는지 확인하고 없다면 파일에서 읽어들인다
2. 버퍼 풀의 해당 페이지에서 갱신을 수행한다
3. 2의 갱신 내용이 커밋과 함께 로그에 기록된다. 버퍼 풀에 갱신되었지만, 아직 데이터 파일에 써지지 않은 페이지는 버퍼풀 내에서 더티 페이지로 다룬다
4. 데이터 페이지는 나중에 적당한 타이(체크 포인트)밍에 정리되어 데이터 파일로 써진다
5. 4의 체크포인트 이전 로그 파일은 불필요해진다. 갱신과 더불어 1부터 순서가 반복된다

**크래시 발생시 각 구조의 상태**

- WAL: 마지막으로 커밋된 트랜잭션의 갱신 정보를 가진다
- 데이터베이스 버퍼: 크래시로 내용이 소실된다
- 데이터베이스 파일: 최종 체크포인트까지 갱신 정보를 가진다

크래시(예를 들어 MySQL 서버의 비정상적 종료)시, 체크포인트 이후의 WAL로그를 데이터베이스 파일에 반영

⇒ 롤 포워드

### 백업과 복구

DBMS의 복구 구조가 존재하지만 논리적 파괴(DDL 문에 따른 테이블 파기)나 물리적 파손(디스크 장치 고장)에는 대응이 불가능하다. 따라서 주기적으로 백업하고 그를 이용해 복원이나 복구하는 것이 좋다.

**PIRT?**

Point-in-time Recovery: 백업 이후의 임의의 시점으로 복원하는 것

실행된 갱신을 기록한 로그를 보존해서 복원한 데이터베이스에 순차 반영해서 복원할 수 있다

**바이너리 로그**

MySQL에서 PIRT를 위해 사용하는 로그(InnoDB 포함 모든 MySQL)

InnoDB 로그는 크래시 복구에만 이용(InnoDB 전용)

**백업의 관점**

1. 핫 백업(온라인 백업) vs 콜드 백업(오프라인 백업)

백업 시 데이터베이스의 상태에 따라 구분 → 백업 도중 DB 접근이 가능한지 안한지

- 핫 백업: 트랜잭션 구조 or 특수 로그 지정 or OS나 하드웨어의 스냅샷을 사용하기도!
2. 논리 백업 vs 물리 백업
- 논리 백업: SQL기반 텍스트 백업(장애가 발생한 이유를 알 수 있다, 이식성 우수, 파일이 큼)
- 물리 백업: 데이터 영역을 그대로 덤프하는 이미지로 바이너리 형식으로 기록(가볍고 빠름, 호환 어렵)
3. 풀 백업 vs 부분 백업
- 풀 백업: 전체 백업(단순, 시간이 오래 걸림, 용량이 많이 필요)
![Untitled](https://t1.daumcdn.net/cfile/tistory/992364475CCED7DA2E)
- 부분 백업: 풀 백업 후 이후 갱신된 데이터를 백업(빠르고 용량이 작음, 복원 절차가 복잡)
- 증분 백업

![Untitled](https://t1.daumcdn.net/cfile/tistory/99565D4C5CCED8191A)
- 차등 백업

![Untitled](https://t1.daumcdn.net/cfile/tistory/993ED7425CCED8621F)

**롤 포워드 리커버리**

현재 데이터 베이스 = 풀 백업한 데이터 + 풀 백업 후 얻은 모든 증분 백업(바이너리 로그)


### 데이터 베이스 관리 시 주의점

- 백업 파일은 데이터베이스와 다른 디스크 장치로 나눠 보관할 것
- 가능하면 물리적으로 분리하는 것도 좋음
- 데이터베이스 장애는 자연 현상. 언제나 일어날 수 있음을 기억하고 대책을 세우고 비율을 줄이기 위해 노력해야함

→ 백업과 복구에 걸리는 시간, 부하 측정해 운영하기

- 백업을 필요로 하는 시스템의 상황에 맞게 백업 방식을 선정할 것
Empty file removed 09장/empty.txt
Empty file.