Skip to content
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
147 changes: 147 additions & 0 deletions keyword/chapter00/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
- PK, FK란?

PK (Primary Key-기본 키)

- 테이블에서 각 데이터를 고유하게 식별하는 기본 키
- 중복이나 NULL 불가
- 테이블당 1개

FK (Foreign Key-외래 키)

- 다른 테이블의 기본키(PK)를 참조하여 테이블 간의 관계를 정의하는 키
- 중복이나 NULL 가능
- ERD란?

엔티티들 간의 관계를 나타낸 데이터베이스 설계도

기본 요소로는 entitiy, attribute, relationship이 있다.

- entity : 정보의 단위로 테이블
- attribute : 엔티티의 상세 정보로 칼럼
- relationship : 엔티티와 엔티티 간의 연결 상태
- 연관관계란? 그리고 연관관계를 설정하는 방법은?

연관관계(relationship)

- 테이블과 테이블 사이의 연결 상태(두 개의 엔티티간의 관계)
- 1:1
- 1:N(일대다)
- 한 쪽 엔티티의 데이터 하나가 다른 쪽 엔티티의 여러 개의 데이터와 연결
- N:M(다대다)
- 중간 연결 테이블을 하나 더 만들어서 1:N - N:1 로 표현

- 정규화란?

이상 문제를 해결하기 위해

데이터베이스 내의 데이터 구조를 조직화하고 최적화하는 과정.

목적 → 데이터 중복을 제거하고, 효율성을 향상시키며, 데이터 무결성을 보장한다.

**이상 종류**

- 삽입 이상 : 데이터 삽입 시 의도와 다른 값들도 삽입
- 삭제 이상 : 데이터 삭제 시 의도와 다른 값들도 연쇄 삭제
- 갱신 이상 : 속석값 갱신 시 일부 튜플만 갱신되어 모순 발생

**정규화 종류**

- 제1 정규화 (1NF)
- 모든 속성(각 칼럼)이 하나의 값을 가지도록 하는 과정
- 하나의 카테고리에 책이 여러 권 있더라도 각 칸에 값 하나씩만 들어가도록
- 갱신 이상과 삭제 이상 해결
- 제2 정규화 (2NF)
- 제1 정규화를 완료한 테이블에서, 부분 함수 종속성을 제거하는 과정
- 기본 키에 일부분에만 의존하는 정보는 따로 빼낸다
- 기본 키가 [회원 ID + 상품 코드] 일 때, 회원 이름은 회원ID에만 종속되고, 상품 코드에는 의존되지 않기 때문에 회원 이름은 따로 빼내야 한다.
- 제3 정규화 (3NF)
- 제2 정규화를 완료한 테이블에서, 이행적 함수 종속성을 제거하는 과정
- 이행적 함수 종속이란 A→B 종속, B→C 종속, A→C 종속인 관계?

![image.png](attachment:fc9262c2-ad2c-47ae-82aa-916aaef2ee34:image.png)

- 위와 같은 상황에서 교수 이름은 교수 ID를 거치지 않더라도 강의 ID만을 통해 알 수 있다.
- 반 정규화란?

정규화의 일부를 되돌려, 데이터의 중복을 의도적으로 허용하고, 데이터베이스의 성능을 향상시키는 과정이다.

데이터를 더 빠르게 조회할 수 있게 되지만, 데이터 중복으로 인해 데이터 무결성이 저하될 수 있다.

반정규화 대상

- 수행 속도가 많이 느린 경우
- 데이블의 조인 연산을 지나치게 사용하여, 데이터 조회하는 것이 기술적으로 어려운 경우
- 데이블에 많은 데이터가 있고, 다량의 범위 혹은 특정 범위를 자주 처리해야 하는 경우

장점

- 데이터를 빠르게 조회할 수 있음
- 조인을 제거하기 때문에 검색 시간이 최적화

단점

- 데이터의 삽입, 삭제, 수정 등 갱신 시 비용이 높아짐
- 데이터간의 일관성이 깨질 수 있음

- DB에서의 상속 관계 표현은 어떻게 하는가?

DB에서는 상속 관계를 표현하기 위해 슈퍼타입/서브타입 모델링 기법을 사용한다.

1. **Join 테이블 전략**
- FK를 이용한 Join을 통해 데이터 조회 방식
- 부모 클래스와 자식 클래스를 각각 테이블로 만들고, 자식 테이블이 부모 테이블의 PK를 받아 PK이자 FK로 사용한다.

**장점**

- 데이터가 중복되지 않는다.
- 설계가 깔끔하고, 외래키 참조 무결성을 지키기 좋다

**단점**

- 데이터 조회 시 JOIN을 많이 써야 해서 쿼리가 복잡해지고 성능이 조금 떨어진다.
2. **단일 테이블 전략**
- 부모와 자식의 모든 변수를 하나의 테이블에 넣는 방식
- 어떤 자식 데이터인지 구분하기 위한 구분 칼럼이 추가된다

**장점**

- JOIN이 필요 없어서 조회 성능이 가장 빠르고, 쿼리가 단순하다.

**단점**

- 자식마다 사용하는 칼럼이 달라, NULL이 많이 쓰이고 지저분해진다.
3. 구현 클래스 테이블 전략
- 부모 테이블 없이, 자식 클래스마다 각각 모든 정보를 담아 테이블을 만든다.

장점

- 특정 자식 데이터만 조회할 때 빠르다.

단점

- 여러 자식 테이블을 한꺼번에 조회할 때 성능이 많이 떨어지고, 관리가 어렵다
- 인덱스란?

추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다.

인덱스는 데이터베이스 내의 특정 칼럼(열)이나 칼럼들의 조합에 대한 값과 해당 값이 저장된 레코드(행)의 위치를 매핑하여 데이터베이스 쿼리의 성능을 최적화하는 데 중요한 역할을 한다.

장점

- 검색 대상 레코드의 범위를 줄여 검색 속도를 빠르게 할 수 있다.
- 중복 데이터를 방지하고, 특정 칼럼의 유일성을 보장할 수 있다.

단점

- 인덱스 생성에 따른 추가적인 저장 공간이 필요하다 (해당 정보를 담은 MYI 파일 생성)
- 삽입, 삭제, 수정 작업 시에도 인덱스를 업데이트해야 하므로 성능 저하가 발생한다.
- 한 페이지를 동시에 수정할 수 있는 병행성이 줄어든다.
- 인덱스 생성 시간이 오래 걸릴 수 있다.

인덱스 사용하는 경우

1. 대량의 데이터를 검색하는 경우
2. 정렬된 결과를 출력하는 경우
3. 조인 연산을 수행하는 경우
4. 유니크한 값을 가져오는 경우
5. 검색 빈도가 높은 경우
61 changes: 61 additions & 0 deletions keyword/chapter01/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
- DB Join이란?

서로 다른 두 개 이상의 테이블을 연결해서 하나의 결과를 만들어내는 연산

- 관계형 데이터베이스는 정규화를 통해 의미 있는 데이터의 집합으로 테이블이 구성되고 각 테이블끼리 관계를 갖게 된다.
- 저장 공간의 효율성과 확장성이 향상된다.
- 하지만 서로 관계있는 데이터가 여러 테이블에 나뉘어 저장되므로 각 테이블에 저장된 데이터를 효과적으로 검색하기 위해 조인이 필요하다.
- 두 테이블 사이에 공통된 칼럼이 있어야 한다.

- Join 종류들
1. INNER JOIN (내부 조인)
- 내부 조인
- 두 테이블을 연결할 때 가장 많이 사용
- 기준 테이블과 Join 테이블의 중복된 값(교집합)을 보여준다.
2. OUTER JOIN (외부 조인)
- 공통된 값이 없더라도 한쪽 테이블의 데이터를 모두 보여주고 싶을 때 사용
- 기준 테이블의 값 + 조인 테이블의 값을 보여준다

![image.png](attachment:e60bdcd6-f006-41fb-9638-86302e83f0b9:image.png)

3. CROSS JOIN
- 두 테이블의 모든 행을 서로 한 번씩 곱하는 방식
- 모든 경우의 수를 구해야 할 때 사용
- (A 테이블 행 수) x (B 테이블 행 수)가 결과 행의 개수가 된다.
4. SELF JOIN
- 자기 자신과 조인하는 방식
- 자기 자신과 조인하므로 1개의 테이블만 사용
- 계층 구조를 표현하거나 같은 집합 내 비교 연산이 필요한 경우 사용된다.

- 트랜잭션이란?

데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 최소 단위를 뜻한다.

4가지 특징

- 원자성
- 트랜잭션이 데이터베이스에 모두 반영되던가, 전혀 반영되지 않아야 한다.
- all or nothing
- 일관성
- 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다
- 트랜잭션이 진행되는 동안 데이터베이스가 변경되더라도 처음 참조한 데이터베이스로 진행하여 사용자가 일관성 있는 데이터를 보게 한다.
- 독립성
- 둘 이상의 트랜잭션이 동시에 실행되고 있는 경우
- 어떤 하나의 트랜잭션이라도, 다른 트랜잭션의 연산에 끼어들 수 없다
- 하나의 특정 트랜잭션이 완료될 때까지, 다른 트랜잭션이 특정 트랜잭션의 결과를 참조할 수 없다.
- 지속성
- 트랜잭션이 성공적으로 완료됐을 경우, 결과는 영구적으로 반영되어야 한다.
- Join on 과 where의 차이점
- ON( 조인 전에 조건을 필터링)
- WHERE (조인 후에 조건을 필터링)

- INNER JOIN에서는 ON 과 WHERE이 차이가 없다.

OUTER JOIN에서 차이

- ON
- LEFT JOIN을 예시로
- 왼쪽 테이블은 다 보여지고,
- 오른쪽 테이블에서 조건에 맞지 않는 데이터는 NULL로 표시된다.
- WHERE
- 일단 두 테이블을 합친 후에, 조건에 안 맞는 행은 아예 다 버린다.
Binary file added mission/chapter00/erd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions mission/chapter01/mission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
### 리뷰 작성하는 쿼리

```sql
// 유저ID(1), 가게ID(3)
INSERT INTO review(member_id, store_id, content, star, create_at)
VALUES(1,3,'음 너무 맛있어요 ...', 5, NOW());
```

### 마이 페이지 화면 쿼리

```sql
// 유저ID(1)
SELECT profile_url, name, phone_number, phone_certification, user_point
FROM user
WHERE user_id = 1
```

### 진행 중, 진행 완료한 미션 모아서 보는 쿼리(페이징 포함)

유저 미션에서 성공 여부,

미션에서 미션 내용, 미션 포인트,

스토어에서 가게 이름을 가져오고,

유저 id가 1 인 것들만 불러온 뒤 페이징 하기

```sql
SELECT m.mission_info, m.point, um.is_complete, s.name
FROM user_mission AS um
JOIN mission AS m ON um.mission_id = m.mission_id
JOIN store AS s ON m.store_id = s.store_id
WHERE um.user_id = 1
ORDER BY um.user_mission.id DESC
LIMIT 10 OFFSET 0;
```

### 홈 화면 쿼리 (현재 선택 된 지역에서 도전이 가능한 미션 목록, 페이징 포함)

```sql
//유저ID(1), 지역ID(안암동 = 2)
SELECT s.name, s.category_id, m.mission_info, m.point, m.mission_id
FROM mission AS m
JOIN store AS s ON m.store_id = s.store_id
WHERE s.region_id = 2
ORDER BY m.mission_id DESC
LIMIT 10 OFFSET 0

-----------------------------------------------------------------
// 해당 지역에서 미션 몇개 성공했나?
SELECT COUNT(*) FROM user_mission AS um
JOIN mission AS m ON um_mission_id = m.mission_id
JOIN store AS s ON m.store_id = s.store_id
WHERE um.user_id = 1 AND s.region_id = 2 AND um.is_complete = true
```