---
# System prepended metadata

title: 5/19 스터디

---

# 5/19 스터디

## 임태현
https://www.notion.so/thsoon/RDB-MySQL-a4cd8d2d89c740ce98271b5219a41c9a
### 트랜잭션과 ACID
1. Atomicity(원자성)
    - 모두 실행이 완료되거나 모두 취소가 되야하는 특징
    - 데이터 정합성 등의 이유로 일련의 연산들을 하나의 트랜잭션이란 단위로 묶는다.
    - 트랜잭션에 속한 연산 중 하나라도 실패하면 DBMS의 회복 모듈에 의해 실행되었던 연산들을 취소한다.
2. Consistency(일관성)
    - 트랜잭션 전 후의 상태는 일관성을 갖는다.
    - 은행 계좌 A, B로 송금하는 예시로 들 수 있다.
3. Isolation(고립성)
    - 트랜잭션 A는 실행 중인 다른 트랜잭션 B가 변경하고 있는 데이터를 훼손할 수 없다.
4. Durability(지속성)
    - 트랜잭션이 성공되면 성공 직후의 상태와 데이터는 영구히 저장된다.


### 트랜잭션 Isolation Level
MySQL를 기준으로 한다.
1. Read UnCommited
    - 동시에 실행 중인 트랜잭션 A, B에 대해서 B가 데이터를 변경하고 Commit을 하지 않아도 A는 그 데이터를 조회할 때 변경된 상태이다. -> Non Repeatable Read
    - Dirty Read: 위에 상황에서 A는 변경된 데이터를 읽는다. 하지만 B가 Rollback을 할 경우 그 후에 A는 변경 전의 데이터를 조회하게 된다.
    - Phantom Read: B가 A와 동시에 참조하는 테이블에 데이터를 추가하면 A는 이전에 보지 못했던 데이터가 추가되어 있다.

2. Read Committed
    - 동시에 실행 중인 트랜잭션 A, B에 대해서 B가 데이터를 변경하고 Commit할 때까지 A는 자신이 시작될 때의 데이터를 읽는다.
    - 즉, B가 Rollback을 해도 Dirty Read가 일어나지 않는다.
    - 하지만 A가 실행 도 중 B가 Commit 하면 A는 이전에 없었던 데이터가 생기거나(Phantom Read) 데이터가 변경되어 있다.(Non Repeatable Read)

3. Repeatable Read
    - 동시에 실행 중인 트랜잭션 A, B에 대해서 B가 데이터를 변경하고 Commit을 해도 A는 자신이 시작할 때의 데이터 그대로 갖고 있다.
    - 이론적으론 데이터 삭제, 추가에 대해선 A가 도중에 데이터가 바뀌지만 MySQL은 바뀌지 않는다. -> Phantom Read 해결
        - MySQL에선 A가 SELECT문으로만 B가 바꾸거나 추가, 삭제한 데이터에 접근하는 경우 자신이 갖고 있던 데이터를 사용한다.
        - 하지만 A도 B가 바꾼 데이터를 갱신하게 되면, B가 바꾸고 Commit한 상태의 테이블로 변한다.

4. Serializable
    - 동시에 실행 중인 트랜잭션 A, B에 대해서 B가 쿼리문으로 참조한 데이터 Row들에 Shared Lock이 걸린다.
    - B가 SELECT 쿼리를 사용한 경우 A가 참조할 수 있지만, 변경 쿼리를 사용할 경우 A가 Shared lock이 걸린 데이터를 참조하는 순간 대기 상태가 된다.
    - 대기 상태는 B가 Commit or Rollback을 해 Shared Lock이 풀리는 상황 또는, Timeout이 발생한 상황이다.

### 파일 시스템의 단점
1. 데이터의 불일치성, 중복성 발생
    - 특정 정보가 두 개 이상의 파일에 기록되어 있을 때 수정 작업을 한다면, 모두 수정하지 않지 않으면 데이터의 정합성이 맞지 않는다.
    - 특정 정보가 두 개 이상의 파일에서 필요로 할 때, 파일들이 포맷이 다르면 눈물을 머금고 중복된 데이터를 갖고 있어야 한다.

2. 데이터 접근성이 안좋다.
    - 새로운 작업을 하기 위해선 새로운 프로그램이 필요하다.

3. 데이터 고립성
    - 포맷이 다른 파일을 다루기 위해 필요한 프로그램을 만들거나 사용하기 어렵다.
    - 즉, 데이터 공유가 어려워져 데이터 고립이 생긴다.

4. 무결성 제약조건
    - 파일에 입력한 데이터가 부적절한 데이터인지 파악할 수가 없다.

5. 갱신의 원자성이 없다.
    - all or nothing 작업이 불가능하다. -> 트랜잭션이 없다.
    - 즉 파일에 대한 갱신이 부분적인 갱신만 일어나 일관성을 유지하기 어려움

6. 다수의 접근을 제어할 수 없다.
    - 동시 접속을 제어하지 못해 파일 내용에 대한 일관성을 유지하기 어려움

### Partioning
#### Partioning 이란?
- 파티셔닝은 한 테이블을 여러 테이블로 분리해 저장하는 솔루션이다.
- 파티션을 적용하는 테이블에선 Primary Key를 지정하면 안된다.
    - 지정하게 되면 Primary Key를 기준으로 정렬되기 때문이다.
    - Primary Key를 사용하려면 파티션에도 Primary Key 속성을 지정해줘야 한다.
    - 파티션 테이블엔 외래 키를 사용할 수 없다.

#### 파티션을 사용하는 이유
하나의 테이블에 데이터 양이 거대해져 인덱스의 크기가 거대해진 경우 성능이 느려질 뿐더러 갱신 작업할 때 인덱스의 갱신 작업이 Overhead가 된다.
즉, 하나의 Layer를 추가해, Full Scan 범위를 좁혀준다.

#### Partioning VS Sharding
- Sharding(수평 파티셔닝)
    - Sharding은 Partioning의 부분 집합
    - 테이블의 Row 단위로 분산 시켜 저장하는 것으로, 샤드 키를 정하고 그 기준으로 데이터를 나눈다.
    - 파티션들로 데이터가 나뉘어지기 때문에 요청된 데이터의 키를 샤드키로 매칭한 다음 파티션으로 매핑해줘 분할된 데이터 집합을 검색하기 때문에 검색 속도가 빨라진다.
    - 하지만 서버간의 연결 과정이 많아지며, 서버 하나가 고장나면 데이터 무결성이 깨진다.

- 수직 파티셔닝
    - 자주 사용하는 Column만을 분리시켜 성능을 향상시킨다.
    - 필요한 Column의 데이터들만 올릴 수 있기 때문에 한 번에 읽는 데이터 수가 현저히 줄어 IO 측면에서 성능상 이점이 있다.

## 최지수
### GET
- Select의 성향을 가지고 있다. 서버에서 어떤 데이터를 가지고 와서 보여주는 용도이지 서버의 값이나 상태를 바꾸지는 않는다.
- 요청을 전송할 때 필요한 데이터를 Body에 담지 않고, URL의 끝에 쿼리스트링을 통해 전송한다.
- 전송하는 길이에 제한이 있다.
- 동일한 요청을 여러 번 수행하더라도 동일한 응답이 와야한다.

### POST
- 서버의 값이나 상태를 바꾸기 위해서 사용한다. 
- 요청을 전송할 때 Body에 담아서 전송한다.
- HTTP 메세지의 Body는 길이의 제한 없이 데이터를 전송할 수 있어서 데용량의 데이터를 전송할 수 있다.
- 서버에게 동일한 요청을 여러 번 전송해도 응답은 항상 다를 수 있다.

### Index
인덱스는 어떤 데이터가 어디에 있다는 위치 정보를 가지는 주소록 같은 개념이다.

인덱스가 있으면 모든 블록을 다 읽지 않고 원하는 데이터가 있는 블록 주소를 찾아내서 그 블록만 메모리로 복사해오면 되기 때문에 작업을 빨리 끝낼 수 있다.

읽기 성능을 향사시키기 위한 자료구조라고 할 수 있고 B+-Tree, Hash 두 가지가 있다.


#### B-Tree Index
실시간으로 데이터가 입력되고 수정되는 환경에서 사용된다. 값의 종류가 많고 중복되는 값이 적은 경우 사용하면 좋다. 일반적으로 사용된다.

컬럼의 값을 변경하지 않고 값의 앞 부분만 잘라서 관리하여 인덱싱하는 알고리즘이다. 인덱스 테이블을 따로 관리하며 인덱스 구조체 내에서는 항상 정렬된 상태를 유지하고 있다.

**구조**
트리 구조로 최상위에 루트노드가 존재하고 자식 노드가 붙어있는 모양이다. 가장 하위에 있는 노드를 리프 노드라 하고, 중간 노드를 브랜치 노드라고 한다.

인덱스의 리프노드는 항상 실제 데이터 레코드를 찾아가기 위한 주소 값을 가지고 있다.


#### Hash Index
칼럼의 값으로 해시 값을 게산해서 인덱싱하는 알고리즘으로 매우 빠른 검색을 지원한다.
동등 비교 검색에는 최적화돼 있지만 값을 변형해서 인덱싱하므로, 특정 문자로 시작하는 값으로 검색을 하는 등 값의 일부로만 검색하고자 할 때는 사용할 수 없다. 범위를 검색하거나 정렬된 결과를 가지고 오는 것도 마찬가지이다.

메모리 기반의 테이블에 주로 구현돼 있으며 디스크 기반에서는 거의 사용하지 않는다.

해시 인덱스의 큰 장점은 실제 키 값과는 관계없이 인덱스 크기가 작고 검색이 빠르다는 것이다. 트리 구조가 아니므로 검색하고자 하는 값을 주면 해시 함수를 거쳐 찾고자 하는 키값이 포함된 버킷을 알아낼 수 있다.
> 버킷은 해시 값(인덱스)과 실제 값의 주소를 연결해 놓은 저장 공간

#### 주의사항
insert 하는 경우 index에 대한 데이터도 추가해줘야 하므로 성능 손실이 생긴다.

delete의 경우 Index값은 삭제하지 않고 사용 안한다는 표시만 한다. 즉 row의 수는 그대로라서 실제 데이터와 index데이터의 개수가 다를 수 있다.


## 문예지
### Scale Up/Down & Scale In/Out
> Scale Up/Down
> 
- Scale Up(수직 스케일)
  - 현재 서버보다 고성능의 서버로 바꾸는 것
  - 프로그램 코드를 재작성하거나 아키텍쳐를 변경할 필요가 없음
  - 비용이 많이 발생
  - 비용 대비 효과가 낮음
  
- Scale Down
    - scale up과 반대로 서버 성능을 낮추는 것

> Scale In/Out
> 
- Scale Out(수평 스케일)
    - 접속가능한 서버(비슷한 성능 혹은 낮은 성능)수를 늘려 확장하는 것
    - 클라우드 서비스에서 권장하는 서버 확장 방식
    - 비교적 저럼한 서버들로 구성 :arrow_right: 비용 절감
    - 만약 일부 서버의 장애가 생겨도 전체 서비스가 중단되지는 않음
    - 추가 확장 용이
    - 분산처리에 대한 경험과 노하우가 없으면 힘듦
    - 처음부터 분산환경에 맞춰 코드를 설계하지 않으면 scale out으로 재구성하기 어려움
    
- Scale In
    - scale out과 반대로 서버 수를 줄이는 것

<br>

### MVC / MVP / MVVM
> 패턴이 등장한 이유
> 
각 계층을 분리시킴으로써 코드의 재사용성을 높이고 불필요한 중복을 제거하기 위해

> MVC
> Model + View + Contoller
> 
- 모든 입력은 controller에서 처리 :arrow_right: 입력에 해당하는 model 업데이트 :arrow_right: model을 보여줄 view 선택
- view : controller = M : 1
- view는 컨트롤러를 참조하지 않음 :arrow_right: view는 model을 사용해 업데이트
- model은 view를 간접적으로 참조
- view랑 model은 서로의 의존성을 피할 수 없음
- 종류
  - spring(java)
  - lalavel(php)
  - express(node)
  - django(python)
  - ruby on rails(ruby)

> MVP
> Model + View + Presenter
> 

![](https://i.imgur.com/UwXUm3g.png)

- presenter? view에서 요청한 정보를 model로 부터 가공해서 view로 전달하는 부분
- 입력이 view에서 처리
- view : presenter = 1 : 1
- view와 presenter는 서로를 참조
- view는 presenter를 사용해 model을 업데이트
- view와 model의 의존성은 없어지지만 view와 presenter는 매우 강한 의존성을 가짐

> MVVM
> Model + View + ViewModel
> 

![](https://i.imgur.com/fS5mSE7.png)

- view에 직접 input
- view : view model = M : 1
- view model은 view를 참조하지 않음
- model은 view model을 사용해 업데이트
- view model 설계가 쉽지 않음
- 데이터 바인딩을 위해 boilerplate code를 짜야함 :arrow_right: 간단한 view나 로직을 만들 때는 배보다 배꼽이 큰 경우도 많음
- 종류
    - vue.js
      (vue.js 공식 가이드 들어가보면 Vue.js is focused on the ViewModel layer of the MVVM pattern 이라고 적혀있다, 프론트 프레임 워크들은 다 vm을 쉽게(?) 구현하는데 초점을 맞춘 것일까?? 리액트 봤는데 1도 모르겠다..프론트도 좀 할 수 있으면 좋을텐뎅)
    - react
      (react는 초점이 view에 맞춰짐. 그래서 프레임워크보단 라이브러리 성향이 더 강함)
    - android
    - ios

1. View에 입력이 들어오면 Command 패턴으로 ViewModel에 명령
    - command 패턴
      실행될 기능을 캡슐화함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 패턴
        - 아직 디자인 패턴은 잘 모르게쯤..짜기 바쁜 것..
2. ViewModel은 필요한 데이터를 Model에 요청
3. Model은 ViewModel에 필요한 데이터를 응답
4. ViewModel은 응답 받은 데이터를 가공해 저장
5. View는 ViewModel과의 Data Binding으로 자동 갱신
    - Data Binging
      Model과 UI 요소 간의 싱크를 맞춰주는 것
