diff --git a/keyword/chapter01/keyword.md b/keyword/chapter01/keyword.md new file mode 100644 index 0000000..932b8a8 --- /dev/null +++ b/keyword/chapter01/keyword.md @@ -0,0 +1,62 @@ +### DB Join이란? + + **DB Join :** 두개 이상의 테이블이나 데이터베이스를 연결하여 데이터를 조회하는 방법 + + - 자신이 조회하고 싶은 컬럼이 다른 테이블에 있을 경우 주로 사용하며 여러 개의 테이블을 마치 하나의 테이블인 것처럼 활용하는 방법이다. + - 보통 Primary key 혹은 Foreign key로 두 테이블을 연결한다. (테이블을 연결하려면 적어도 하나의 컬럼은 서로 공유되고 있어야 한다.) + +
+ +### Join 종류들 + + **INNER JOIN** : 두 테이블에서 조인 조건에 일치하는 값이 양쪽에 모두 존재하는 행만 합쳐서 보여준다. + + - 쉽게 말해 교집합이다. 어느 한 쪽이라도 연결된 데이터가 없으면 결과에서 빠진다. + - 예시 : 댓글과 회원을 조인할 때 탈퇴한 회원이 쓴 댓글이나 아직 댓글을 안 쓴 회원은 제외하고 실제로 댓글을 쓴 회원의 정보만 보고 싶을 때 쓴다. + + **OUTER JOIN :** 조건에 맞지 않아도 한쪽 테이블의 데이터는 무조건 다 가져오고 싶을 때 사용한다. + + - LEFT JOIN : 왼쪽 테이블의 모든 행을 가져온다. 오른쪽 테이블에 매칭되는 데이터가 없으면 NULL + - RIGHT JOIN : LEFT JOIN의 반대. 오른쪽 테이블의 모든 행을 기준으로 가져온다. + - FULL JOIN : 합집합. 양쪽 테이블의 모든 데이터를 다 가져온다. 서로 연결되지 않는 데이터들도 모두 포함되며, 빈 곳은 전부 NULL. + + **CROS JOIN :** 조건 없이 두 테이블의 모든 행을 곱하는 방식 + + - 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행의 모든 조합을 구한다. + - A 테이블 행이 10개, B 테이블 행이 5개면 총 50개의 결과가 나온다. + +
+ +### 트랜잭션이란? + + **트랜잭션** : 데이터베이스에서 하나의 거래를 안전하게 처리하도록 보장해주는 것 + + - 더 이상 쪼갤 수 없는 최소 단위 + - ALL OR NOTHING 개념이다 (전부 성공 or 아예 하나도 안 한 것처럼 되돌리기) + - 모두 commit 하거나 모두 rollback + - commit (확정): 모든 작업이 성공적으로 끝났으니 DB에 영구적으로 반영하라는 명령어 + - rollbac (취소)**:** 작업 도중 에러가 났으니 트랜잭션 시작 전 상태로 모든 작업을 되돌리라는 명령어 + - 예시 : 계좌이체에서 보내는 쪽과 받는 쪽의 행동이 다르면 안되기 때문에 하나의 트랜잭션으로 묶는다 + + **트랜잭션 원칙** + + - **원자성**: 트랙잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 실패해야 한다. + - **일관성**: 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다. + - **격리성**: 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 동시에 같은 데이터를 수정하지 못하도록 해야한다. + - **지속성**: 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템에 문제가 발생해도 데이터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구할 수 있어야 한다. + +
+ +### Join on 과 where의 차이점 + + **JOIN ON** : JOIN 전에 조건을 필터링 ⇒ 이 조건에 맞는 것들만 JOIN + + - 결합 조건과 필터링 조건이 분리됨 (ON절 : 테이블 간의 연결조건, WHERE절 : 최종 결과 필터링) + + **JON WHERE** : JOIN 후에 조건을 필터링 ⇒ 일단 JOIN 진행 후, 그 다음 이 조건에 맞는 것들만 남긴다 + + - 결합 조건과 필터링 조건이 혼합됨 (WHERE절: 두 가지 역할을 모두 수행) + + SQL문 실행 순서상 ON 절이 WHERE 절보다 먼저 실행되기 때문에 **OUTER JOIN**에서 WHERE를 잘못 사용하면 원하는 결과가 안 나올 수도 있다. + + ⇒ OUTER JOIN에서 WHERE 사용하게 되면 조인이 완전 끝난 결과물에 데이터 걸러내게 된다. 만약 조건이 맞지 않는다면 왼쪽 혹은 오른쪽 테이블 데이터까지 모두 사라진다. LEFT or RIGHT JOIN을 사용했음에도 INNER JOIN과 동일한 결과가 나올 수 있다. \ No newline at end of file diff --git a/mission/chapter01/ERD.png b/mission/chapter01/ERD.png new file mode 100644 index 0000000..c0d8dd6 Binary files /dev/null and b/mission/chapter01/ERD.png differ diff --git a/mission/chapter01/image1.png b/mission/chapter01/image1.png new file mode 100644 index 0000000..984a159 Binary files /dev/null and b/mission/chapter01/image1.png differ diff --git a/mission/chapter01/mission.md b/mission/chapter01/mission.md new file mode 100644 index 0000000..48781ca --- /dev/null +++ b/mission/chapter01/mission.md @@ -0,0 +1,83 @@ +### 피어리뷰 (Spring A팀 미키) + +![image1](image1.png) + +**리뷰 내용** + +1번 쿼리 +- ERD 테이블 이름과 동일하게 REVEIW -> review로 변경하면 좋을 것 같아요! +- 위와 동일하게 모두 소문자로 변경하면 좋을 것 같아요! + +2번 쿼리 +- SQL문에서는 '로만 적는걸로 알고있는데 한 번 확인해주세요!! + +3번 쿼리 +- 저는 AS가 테이블 이름을 짧게 줄이는 기능만 있는줄 알았는데 별칭 기능도 있었군요! +- 제가 알기로는 SELECT, FROM, JOIN 모든 곳에서 AS 사용해도 되는 것으로 알고 있어서 mission AS m이 맞을 것 같아요! +- cursor paging 방법까지 쓰신게 인상깊어요! + +4번 쿼리 +- created_at()을 front에 넘기는게 아니라 직접 시간 넘겨주는게 멋있어요! + +
+ +### 1. 리뷰 작성하는 쿼리 + +- 리뷰 테이블에서 유저 id, 가게 id, 평점, 리뷰 내용을 입력 받는다 + +```sql +INSERT INTO reviews (user_id, store_id, star, content, created_at, updated_at) +VALUES (1, 1, 5, '좋습니다', NOW(), NOW()) +``` + +### 2. 내가 진행중, 진행 완료한 미션 모아서 보는 쿼리(페이징 포함) + +- 먼저 사용자 미션, 미션, 가게 테이블을 조인한다. 그리고 API 호출 시 입력 파라미터로 user_id로 미션 수행 상태인 status를 받도록 했다. (해당 인원의 미션 진행중, 진행완료를 알아야 되기 때문에) 가게의 id, 가게명, 미션 내용, 포인트를 선택했고 updated_at을 기준으로 내림차순 했다. + 페이징 기법은 offset 사용해서 한 페이지에 10개씩 조회되도록 했다. + +```sql +SELECT s.id, s.name, m.condition, m.success_point, um.status +FROM user_missions AS um +JOIN missions AS m ON m.id = um.mission_id +JOIN stores AS s ON s.id = m.store_id +WHERE um.user_id = 1 AND um.status = 'SUCCESS' +ORDER BY um.updated_at DESC +LIMIT 10 OFFSET 0; +``` + +### 3. 마이 페이지 화면 쿼리 + +- users 테이블에서 profile_url, name, email, phone_check, point 가져온다 + +```sql +SELECT profile_url, name, email, phone_number, phone_check,point +FROM users +WHERE id = 1 +``` + +### 4. 홈 화면 쿼리 (현재 선택 된 지역에서 도전이 가능한 미션 목록, 페이징 포함) + + +- '7/10' 부분 : 카운트 쿼리를 사용해서 ‘안암동’ 지역에서 선택한 나의 미션 중에서 성공한 미션의 개수를 센다 + +- 'MY MISSION' 부분 : 가게 이름, 미션 데드라인, 가게 카테고리, 미션 내용, 포인트가 필요하다. 또한 이 미션도 ‘안암동’ 지역에 대한 것이기 때문에 WHERE에 지역 조건을 추가한다. 정렬은 데드라인이 짧은 순으로 했다 또한 페이징 기법은 offset 사용해서 한 페이지에 10개씩 조회되도록 했다. + +```sql +/* '7/10' 부분 */ +SELECT COUNT(*) +FROM user_missions AS um +JOIN missions AS m ON m.id = um.mission_id +JOIN stores AS s ON s.id = m.store_id +JOIN regions AS r ON r.id = s.region_id +WHERE um.user_id = 1 AND um.status = 'SUCCESS' AND r.name = '안암동'; + +/* 'MY MISSION' 부분 */ +SELECT s.name, s.category_id, m.deadline, m.condition, m.success_point +FROM missions AS m +JOIN stores AS s ON s.id = m.store_id +JOIN regions AS r ON r.id = s.region_id +LEFT JOIN user_missions AS um ON um.mission_id = m.id AND um.user_id = 1 +WHERE r.name = '안암동' AND (um.status IS NULL OR um.status != 'SUCCESS') +ORDER BY m.deadline ASC; +LIMIT 10 OFFSET 0; +```