[TIL] 삼성 시그니처: 전화번호부와 서비스단 친구 목록 연동하기
ISSUE 1. 전화번호부와 시그니처에 가입한 유저 연동하기
❓문제상황
- 카카오톡처럼 전화번호부에 추가된 사람을 우리 서비스인
시그니처
에 친구 추가하려는 로직을 구현하려고한다. - 어떻게 전화번호부에 있는 사람이
시그니처
에 가입했는지에 대한 여부를 판단할 수 있을까?
❗해결방법
한 사람씩 가입했는지 DB에 가서 확인한다면?
- 전화번호부에 있는 사람이 1만명이라면? DB를 만 번 갔다와야하나..?
- DB커넥션풀에 제한이 있기때문에 한 명까지 괜찮을수 있어도 연동하고자하는 사람이 천명 만명이 된다면..? 성능 저하가 일어날 수 있기 때문에 이러한 방법은 아니라 판단했다.
- 전화번호부에 있는 사람이 1만명이라면? DB를 만 번 갔다와야하나..?
- 어자피 서비스에 가입한 사람 목록을 조회해야하기 때문에
서버단에서 필터링
을 하기로 했다.
- 그럼 또
for문을 돌면서 전화번호부와 서비스 가입 유저목록을 비교
해야하나?- 그렇다면 전화번호부를 기준으로 서비스 가입 유저목록을 조회해야하기 때문에 이중포문이 걸린다. 하지만 첫번째 방법 처럼 1만명이라면? 또 서비스에 가입한 사람이 천만명이라면???
- 시간복잡도가 O(N*M)이 되게 되는데 성능 속도가 사람들이 서비스를 가입할 때마다 떨어진다는게 이상하다고 판단했다.
- 그렇다면
O(1)로 서비스 유저를 찾을 수 있는 방법
은 없을까?- 전화번호로 가입한 사람을 판단할 수 있기 때문에 Map을 사용해서 key는 전화번호, value는 유저정보로 서비스 가입 유저 목록을 들고오려고한다.
- 또, 전화번호부의 자료형태도 처음에는 자료구조인 Set으로 전화번호를 담아서 가져왔는데 나중에 Map으로 바꿨다.
- 마찬가지로 key는 전화번호, value는 사용자의 전화번호부에 저장한 정보
- Map은 key, value모두
set으로 바꿀 수 있다는 점으로 교집합, 여집합을 사용
하려고한다.
1. 전화번호부에 등록된 사람 중에 서비스에 가입한 사람 찾기
- 연동하려는 유저의 전화번호부에 있는 전화번호 INTERSECT 서비스 가입자의 전화번호
= 현재 서비스에 가입되어 있고 유저 전화번호부에 등록되어 있는 사람
2. 아직 친구로 등록되지 않은 유저 친구목록에 추가하기
- 1번에서 구한 친구목록 DIFF 현재 서비스에 등록되어 있는 친구 목록
= 새로 추가해야 할 친구 목록
3. 새로추가해야할 친구 목록 DB반영
- DB조회를 2번으로 줄일 수 있었다.
- 시그니처에 가입한 유저 목록
- 해당 유저와 친구인 유저 목록
- 새로 추가해야할 친구 목록은 마지막에 saveAll로 반영해주었다.
4. DB를 조회하면서 N+1문제 고려
- JPA에서는 pk만을 가지고 객체를 다루면 Proxy를 사용하기 때문에 따로 DB 조회 쿼리가 나가지 않는다.
- 그러나 pk를 제외한 다른 컬럼에 접근할 경우 Lazy/Eager과 관계없이 쿼리문이 나가게된다.
- 이러한 경우를 피하기 위해서 Friend 엔티티를 구성할 때 친구의 정보는 전화번호부에서 가져오고 객체 자체를 넘겨줄때만 Member를 사용하였다.
This post is licensed under CC BY 4.0 by the author.
Comments powered by Disqus.