일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- nodeJS
- typescript
- JWT
- 노드
- rebase
- pm2
- wecode
- django westagram
- 프로미스
- OSI7계층
- node
- Jest
- westagram
- CORS
- status code
- javascript
- 장고초기세팅
- TypeError: this.boardRepository.createBoard is not a function
- manytomanyfield
- bcrypt
- 자바스크립트
- 스코프
- async/await
- 호이스팅
- 트랜잭션
- crud2
- 실행 컨텍스트
- docker
- on_delete
- Django
- Today
- Total
될때까지
((기업협업5)) 팔로우, 팔로워 raw query로 데이터 가져오기 본문
지난주 금요일, 기업협업으로 나가있는 회사에서 팔로우, 팔로워 조회 기능을 구현해볼 수 있는 기회를 줬다.
이제까지 해왔던 개념이겠거니 하고 싶게 생각했는데, 집단지성을 이용했음에도 불구하고 풀지못했다. 하지만 사수님은 뚝딱뚝딱 쉽게 해결해서 보여주셨고 난 왜 이걸 못했을까 자책하며 멘탈이 많이 나간 주말이였다 안녕 내 멘탈... 그렇게 토요일은 공부할 기분이 아니라며 핑계대고 하루종일 뒹굴거렸다. ^^
지친 멘탈을 회복하고 나니 어떻게 해당 데이터를 가져올 수 있었을까 궁금해졌고 나도 구현해보고 싶었다. 그래서 예제 테이블을 만들고 실습 하기 도전도전!
먼저 그 때의 상황이 전부 다는 기억안나지만 얼추 비슷하게 따라해보며 실습해보자. 상황은 아래와 같다.
- users 테이블의 속성으로 id, name, gender가 있다.
- follows 테이블의 속성으로 id, from_user, to_user가 있다.
- blocks 테이블의 속성으로 id, from_user, to_user가 있다.
- images 테이블의 속성으로 id, name, image가 있다.
- 위 테이블에는 모두 FK가 없다. 데이터의 수정이 일어나는 경우 불편할 뿐더러, 어떻게 확장될지 모르므로 구축이 완료된 후에 FK 설정을 한다고 했다.
- 유저의 팔로우 목록을 보여줄 때, 사용자가 차단한 사람은 유저의 팔로우 목록에 나타나지 않아야한다.
- 유저와 사용자가 모두 팔로우한 사람이 위에 나타나고, 유저만 팔로우한 사람은 아래에 나타나야한다.
- 프로필 이미지는 image테이블에 존재한다.
- 실제로는 users, blocks, images 테이블에 type이라는 컬럼이 존재했고 이 type에 따라 다른 데이터를 다뤘는데(예를 들어서 blocks_type=1은 사용자 차단, blocks_type=2는 메세지 차단 등) 지금 이 포스팅의 목적은 join을 다루는 것으로 생략하겠다.
관계형 데이터베이스인데 FK가 없다니 너무 신기했었다!! FK가 아닌 다른 컬럼으로 조인을 걸 수 있다니 그것도 신기했는데 지금 생각해보면 당연히 되는 작업(?)이였다. 조건이 같으면 join을 걸 수 있으니까 FK는 하나의 방법이였던 것이다!
FK를 쓰지 않는 이유는 부모 테이블의 구조를 변경해야할 때 자식 테이블의 구조에 따라 변경 가능 여부가 달라진다. 유지보수와 관리의 용이함을 위해(수정이 껄끄럽기 때문에) 그리고 확장성을 위해 FK없이 개발한 이후에 FK를 걸어준다고 한다.
실습
테스트 DB를 만들고, 테이블명을 아래와 같이 생성했다.
사심을 가득 담아 데이터도 집어넣었다(이미지 테이블은 일단 보류!)
팔로우/팔로워 조회 기능은 inner join vs left join중 어떤 걸 사용해야할까?
어떤 유저의 팔로우 목록을 조회해야한다. 어떤 join을 사용해야할까? 먼저 inner join을 사용한 경우 데이터가 어떻게 나올지 실습해보자.
inner join
여기서 inner join을 사용해 users와 follows를 연결하면 어떻게 조회될까? inner join은 두 테이블의 교집합 즉, 겹치는 데이터만 조회되기 때문에 팔로우하고 있지 않는 이이경은 나타나지 않아야한다.
inner join은 기준 테이블과 조인 테이블 모두에 존재하는 데이터(교집합 개념)만 조회된다. 그럼 outer join을 사용하면 어떻게 될까?
left join
(inner) join과 달리 left (outer) join은 기준테이블-users에 해당하는 데이터는 전체 조회되고, 조인 테이블에 있는 데이터들도 가져오되 연결고리가 없다면 null값으로 가져온다. 그래서 아무도 팔로우하고 있지 않는 이이경은 null값을 보여준다.
결론
users와 follows를 inner join하면 유저들 중에 팔로우하고 있는 유저들만 조회된다. 하지만 내가 팔로우한 유저인지 아닌지의 여부에 따라 데이터가 정렬되야하기 때문에 내가 팔로우를 한 유저도 나와야하고 팔로우하지 않은 유저도 조회되야한다. 즉 교집합이 아닌 합집합 개념이기 때문에 left join을 사용하는 게 적합하다.
차단된 유저는 조회되면 안된다.
차단된 유저는 조회되면 안되니까 = 연산자가 아닌 부정 연산자를 사용해야한다. sql에서 부정연산자는 '!=' 또는 '<>'를 사용하면 된다.
팔로우 테이블에서 팔로우 당한 유저가 차단 당한 유저가 아닌 경우만 where절을 사용하여 해당 조건 빼고 가져왔다.
느낀점
몰랐던 개념이 등장하지도 않았고 과제를 진행하면서 썼었던 WHERE절과 JOIN으로 끝낼 수 있었잖아? 바로 SQL문을 작성하려 들지말고 진득하게 생각하는 시간을 갖고 주어진 요구사항을 하나씩 풀어갔었으면 할 수 있었을텐데 라는 생각이 들었다. 잊지말자 문제를 해결할 때 문제를 정확히 인지하고 어떻게 다가가면 좋을지 사고하면서 해결해나가는 습관을 기르자!
'프로젝트 > wecode : 기업협업' 카테고리의 다른 글
((기업협업6)) node.js에 swagger array 연달아 배치하기 (0) | 2022.09.06 |
---|---|
((기업협업6)) node.js에 swagger 적용하기 (0) | 2022.09.06 |
((기업협업4)) router에 때려적었던 지저분한 스파게티 코드 분리하기 (0) | 2022.08.20 |
((기업협업4)) 자바스크립트 try..catch와 에러 핸들링 (0) | 2022.08.19 |
((기업협업4)) AWS : DUMP MYSQL RDS TO LOCAL MYSQL (0) | 2022.08.19 |