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
116 changes: 116 additions & 0 deletions keyword/chaptor01/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
- DB Join이란?

---

**두 개 이상의 테이블을 연결해서 한 번에 조회하는 것**

테이블은 정규화를 진행하면서 데이터가 여러 테이블에 나뉘어 저장된다. 해당 데이터를 조회할 때 여러 테이블의 데이터와 연관되어 있어 함께 조회해야 하는 경우에 사용한다. (PK↔FK 관계)

---

- Join 종류들

---

1. **INNER JOIN** : 양쪽 테이블 모두에 매칭되는 데이터만 반환

ex) members, reviews 테이블을 조회할 때 리뷰를 달지 않은 회원은 조회 대상에서 제외됨

2. **LEFT JOIN**: 왼쪽 테이블을 기준으로 오른쪽 테이블에 매칭이 없으면 NULL을 채워 전부 조회 (WHERE 조건이 오른쪽 테이블 컬럼에 걸리면 NULL행이 전부 필터링 될 수 있음)

⇒ **가장 많이 사용됨**.

3. **RIGHT JOIN**: 오른쪽 테이블을 기준으로 왼쪽 테이블에 매칭이 없으면 NULL을 채워 전부 조회

⇒ 잘 안 쓰임 (reviews 테이블에는 데이터가 있는데 members에 데이터가 없다? → 그냥 테이블 순서 바꿔서 LEFT JOIN을 사용할 수 있음!)

4. **FULL OUTER JOIN** : 양쪽 테이블을 모두 포함 + 매칭 없으면 NULL로 채움

⇒ MySQL에서는 지원을 안함

---

---


- 트랜잭션이란?

---

**데이터베이스에서 여러 쿼리를 하나로 묶은 논리적인 작업 단위**로, 작업의 수행 결과가 ‘전부 성공’ or ‘전부 실패’ 2가지 케이스만 나오도록 보장한다.

[ACID 특성] - 트랜잭션이 보장하는 특성 4가지

1. **원자성 (Atomicity)**

트랜잭션 내에서 실행한 작업들은 마치 하나의 작업처럼 전부 성공하거나 전부 실패해야 한다.

하나라도 실패할 경우 **Roll back** 진행

2. **일관성 (Consistency)**

모든 트랙잭션은 작업 전후로 데이터 무결성을 유지해야 하며, 일관성 있는 데이터베이스 상태를 유지해야 한다.

3. **고립성 (Isolation)**

동시에 진행되는 여러 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다.

⇒ 트랜잭션이 완료되기 전의 중간 상태를 다른 트랜잭션이 볼 수 없어야 한다.

4. **지속성 (Durability)**

COMMIT이 완료된 데이터는 데이터베이스에 영구 저장되어야 한다.


[트랜잭션을 왜 사용할까?]

ex) 입금 상황: 제이 → 준 (5,000원 입금 시도)

1. 제이 계좌 -5,000원 쿼리 A
2. 준 계좌 +5,000원 쿼리 B

이때, 쿼리 A 성공 후 서버 장애 발생 시 소중한 5,000원은 공중 분해가 되는 것인가? 트랜잭션을 사용하면 쿼리 A는 Roll back이 진행되어 전부 없던 일로 된다.

ex) 트랜잭션 A : 제이 → 준 (5,000원 송금 중 상황),

트랜잭션 B : 준 잔고 조회 (고립성 특성으로 인해 불가능)

[Spring boot에서 트랜잭션 사용 과정]

`@Transactional` 어노테이션 사용 시 자동으로 트랜잭션 적용

- 메서드 시작 → 트랜잭션 시작
- 메서드 정상 종료 → 자동 COMMIT
- 메서드 예외 바생 → 자동 Roll back

---
---
- Join on 과 where의 차이점

---

ON: Join할 때 두 테이블을 어떤 기준으로 연결할지 결정하는 조건

WHERE: Join 완료 후 결과에서 필터링하는 조건

[실행 순서]

1. FROM으로 테이블 가져옴
2. ON 조건으로 JOIN 수행
3. WHERE 조건으로 필터링

[LEFT JOIN + ON 조건]

→ 조건 불만족해도 왼쪽 테이블은 유지

→ 오른쪽 테이블 NULL 채워서 가져옴

[LEFT JOIN + WHERE 조건]

→ NULL 행이 자동으로 필터링돼서 제외됨

→ INNER JOIN처럼 동작함

ON member.member_id = reviews.member_id

WHERE reviews.star ≥ 4 (별점 4점 이상만)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions mission/chaptor01/mission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
- (필수) 0주차 때 **직접 설계한** 데이터베이스를 토대로 아래의 화면에 대한 쿼리를 작성


[0주차 erd 설계 수정 부분]

- 미션 테이블 - ‘마감 날짜’ 속성 추가
- 지역 테이블 & 지역 이름 속성 추가
- 사용자-미션 테이블 ↔ 리뷰 테이블 연관관계 삭제
![0주차 erd 설계 수정본](./images/umc_0주차_erd설계_수정본.jpg)


---
### 1. 리뷰 작성하는 쿼리, 사진의 경우는 일단 배제

```sql
INSERT INTO reviews (member_id, store_id, star, content, created_at, updated_at)
VALUES (1, 2, 5, ‘음 너무 맛있어요’, NOW(), NOW());
```
리뷰 테이블에 [사용자 id, 가게 id, 별점, 리뷰 내용, 생성일자, 수정일자] 데이터를 넣는다.

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

```sql
SELECT mm.member_mission_id,
mm.mission_status,
m.mission_condition,
m.reward_point,
s.store_id
FROM member_mission AS mm
JOIN missions AS m ON mm.mission_id = m.mission_id
JOIN stores AS s ON m.store_id = s.store_id
WHERE mm.member_id = 1 AND mm.mission_status = 'COMPLETED'
ORDER BY mm.started_at DESC
LIMIT 10 OFFSET 0;
```
[미션 id, 미션 상태, 가게 id,미션 조건, 보상 포인트]
속성을 가져온다. 미션 테이블과 가게 테이블을 JOIN 하였고
미션 상태가 'COMPLETED'인 것을 WHERE 조건으로 넣었다.

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

```sql
SELECT m.nickname,
m.email,
m.phone_number,
m.point
FROM members AS m
WHERE m.member_id = 1;
```
사용자 테이블에서 [닉네임, 이메일, 전화번호, 포인트] 데이터를 가져온다.
### 4. 홈 화면 쿼리 (현재 선택 된 지역에서 도전이 가능한 미션 목록, 페이징 포함)

```sql
SELECT COUNT(*)
FROM member_mission AS mm
JOIN missions AS m ON m.mission_id = mm.mission_id
JOIN stores AS s ON s.store_id = m.store_id
JOIN regions AS r ON r.region_id = s.region_id
WHERE mm.member_id = 1
AND mm.mission_status = 'COMPLETED'
AND r.region_name = '안암동';

SELECT s.store_name,
s.store_category,
m.mission_period,
m.mission_condition,
m.reward_point
FROM missions AS m
JOIN stores AS s ON s.store_id = m.store_id
JOIN regions AS j ON j.region_id = s.region_id
WHERE r.region_name = '안암동'
ORDER BY m.deadline ASC
LIMIT 10 OFFSET 0;
```
‘안암동’ 기준으로 카운트 쿼리를 통해 총 미션 개수 중 COMPLETED 미션 개수를 센다.

[가게 이름, 가게 카테고리, 보상포인트, 미션 데드라인, 미션 조건] 데이터를 가져온다. 이 쿼리 역시 ‘안암동’ 기준이며 성공 여부를 체크한다.