Post

[TIL] 삼성 시그니처: 전화번호부와 서비스단 친구 목록 연동하기

ISSUE 1. 전화번호부와 시그니처에 가입한 유저 연동하기

문제상황

  • 카카오톡처럼 전화번호부에 추가된 사람을 우리 서비스인 시그니처 에 친구 추가하려는 로직을 구현하려고한다.
  • 어떻게 전화번호부에 있는 사람이 시그니처에 가입했는지에 대한 여부를 판단할 수 있을까?

해결방법

  • 한 사람씩 가입했는지 DB에 가서 확인한다면?
    • 전화번호부에 있는 사람이 1만명이라면? DB를 만 번 갔다와야하나..?
      • DB커넥션풀에 제한이 있기때문에 한 명까지 괜찮을수 있어도 연동하고자하는 사람이 천명 만명이 된다면..? 성능 저하가 일어날 수 있기 때문에 이러한 방법은 아니라 판단했다.
  • 어자피 서비스에 가입한 사람 목록을 조회해야하기 때문에 서버단에서 필터링 을 하기로 했다.


  • 그럼 또 for문을 돌면서 전화번호부와 서비스 가입 유저목록을 비교해야하나?
    • 그렇다면 전화번호부를 기준으로 서비스 가입 유저목록을 조회해야하기 때문에 이중포문이 걸린다. 하지만 첫번째 방법 처럼 1만명이라면? 또 서비스에 가입한 사람이 천만명이라면???
    • 시간복잡도가 O(N*M)이 되게 되는데 성능 속도가 사람들이 서비스를 가입할 때마다 떨어진다는게 이상하다고 판단했다.


  • 그렇다면 O(1)로 서비스 유저를 찾을 수 있는 방법은 없을까?
    • 전화번호로 가입한 사람을 판단할 수 있기 때문에 Map을 사용해서 key는 전화번호, value는 유저정보로 서비스 가입 유저 목록을 들고오려고한다.
    • 또, 전화번호부의 자료형태도 처음에는 자료구조인 Set으로 전화번호를 담아서 가져왔는데 나중에 Map으로 바꿨다.
      • 마찬가지로 key는 전화번호, value는 사용자의 전화번호부에 저장한 정보
    • Map은 key, value모두 set으로 바꿀 수 있다는 점으로 교집합, 여집합을 사용하려고한다.


1. 전화번호부에 등록된 사람 중에 서비스에 가입한 사람 찾기

img1

  • 연동하려는 유저의 전화번호부에 있는 전화번호 INTERSECT 서비스 가입자의 전화번호
  • = 현재 서비스에 가입되어 있고 유저 전화번호부에 등록되어 있는 사람


2. 아직 친구로 등록되지 않은 유저 친구목록에 추가하기

img2

  • 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.