LIKET팀이 태그 데이터를 다루는 방법

민경찬·2024년 6월 15일
9

백엔드

목록 보기
16/22
post-thumbnail

라이켓은 다양한 문화생활 정보를 공유하고 나만의 문화생활 기록을 남길 수 있는 서비스를 제공하고 있습니다.
태그별, 지역별로 관심있는 정보들만 골라보고 쉽게 문화생활을 즐겨보세요.

안녕하세요. 라이켓의 백엔드 개발을 맡고있는 민경찬입니다. 라이켓에서는 장르, 연령대, 스타일 이라는 카테고리 데이터를 다루고 있습니다. 오늘은 저희 서비스에서 해당 카테고리 데이터를 다뤘던 방법에 대해서 얘기해보려고 합니다.


🤔 장르와 연령대, 스타일은 무엇일까요?

왼쪽 이미지는 서비스 메인 페이지입니다.

화면 중간에 팝업스토어, 전시회, 연극, 뮤지컬... 이라고 표시되어 있는 것이 장르입니다.

또한 중간에 #힐링 이라는 메인 컬러로 된 텍스트 볼 수 있습니다. 이는 컨텐츠의 스타일을 나타냅니다.

연령대는 사진에 나와있지 않지만 컨텐츠의 또 다른 카테고리입니다.

이는 모두 사용자가 원하는 컨텐츠를 쉽게 볼 수 있도록 도와주는 분류군들입니다.
서비스에서는 장르, 연령대, 스타일을 태그라는 유비쿼터스 언어로 표현합니다.
(이하 태그라고 표현)


💡 태그 데이터를 저장하는 방법

LIKET에서는 태그 데이터를 별도의 테이블로 관리하고 있습니다.

흔히 카테고리하면 생각할 수 있는 1:N 관계로 이루어져 있습니다.

태그 데이터를 별도의 테이블로 관리할 경우 다음과 같은 장점을 가질 수 있습니다.

  1. DB레벨에서의 엄격한 태그 제한
  2. F-key를 통한 인덱싱
  3. 태그 데이터 추가/수정/삭제 용이

없는 태그와 연결하는 것을 DB 레벨에서 제한할 수 있습니다. 또한 F-key 인덱싱을 통해 특정 장르의 컨텐츠 데이터를 가져오는 것이 더 빨라집니다. 그리고 더 이상 코드 레벨에서 태그 데이터를 다룰 일이 없는 것이죠.

그래서 저희 서비스에서는 태그를 별도의 데이터 테이블로 정규화하여 보관하고 있습니다.

이렇게 뻔한 얘기가 오늘의 주제가 절대 아닙니다.


💡 태그 데이터에 가져오는 방법

오늘 주제의 핵심은 "그래서 태그 데이터를 가져오는 방법은 무엇인가?" 입니다.

처음에는 사진에 나와있는 3가지 API를 통해 태그 데이터를 제공하였습니다. 그러나 변화하는 기획속에서 이 방식이 적합한 것인지에 대한 의문을 가지기 시작했습니다.

일부 변경된 기획: 장르와 연령대, 스타일을 변경할 수 있는 기능은 제공하지 않으며 변경될 때는 반드시 버전 업데이트 시에 변경된다.

태그 데이터가 변경되었을 경우 연결된 컨텐츠 또는 사용자, 리뷰 데이터에 변화가 생길 것으로 우려되어 태그 데이터를 함부로 수정할 수 없도록 기획이 변경되었습니다.

기획 상황에 맞게 백엔드에서도 적절한 조치를 취해줄 필요가 있었습니다.

테이블에 접근한다는 것은 데이터 변화를 실시간으로 적용한다는 것이니까요!

이렇게 변경된 기획에 맞춰 우리는 실시간 API 대신, 더 안정적인 방법을 모색해야 했습니다.


❓ 어떻게 변경하면 좋을까?

태그 데이터를 효율적으로 관리하기 위해 다음과 같은 방법을 고려할 수 있습니다:

  1. 백엔드 JSON 파일 사용: 태그 데이터를 코드 레벨에서 JSON 파일로 관리하여, 버전 업데이트 시에만 변경될 수 있도록 합니다. 이렇게 하면 실시간 데이터베이스 접근 없이도 빠르고 안정적으로 태그 데이터를 제공할 수 있습니다.
  2. 캐싱 전략 도입: 태그 데이터를 캐시하여 일정 시간 동안 변경되지 않도록 하고, 주기적으로 업데이트하여 최신 상태를 유지합니다.

그러나 먼저 태그 데이터의 특징을 먼저 이해할 필요가 있습니다.

태그는 다음의 특징 가지고 있습니다.

  • 각 태그 별로 1~15개 정도의 이름을 가지는 데이터
  • 실시간으로 변경되지 않음
  • 필터링에 사용됨

즉, 태그는 개수가 적고 실시간으로 변경되지 않으며 필터링에 사용되는 데이터입니다.

필터링에 사용된다는 것은 콘텐츠 테이블에 태그에 대한 식별값을 인덱싱해 놓아야 한다는 것을 의미합니다. 태그를 보관하는 테이블은 여전히 필요합니다.

그러나 버전이 바뀔 때만 변경되는 데이터라면 굳이 DB에 실시간으로 접근할 필요가 없다고 생각했습니다.

그래서 라이켓 팀에서는 1번 방법을 사용하기로 하였습니다.


❓ 더 좋은 방법은 없을까?

백엔드 코드 레벨에서도 JSON 형태로 데이터를 보관하고 있다가 전달하는 방식은 데이터베이스에 연결할 필요가 없어서 API를 정말 가볍게 만들 수 있었습니다.

그러나 저희는 API 자체가 필요할까? 라는 의심을 하기 시작했습니다.

실제 페이지 속에서 태그들은 드랍다운 또는 페이지 접근시에 바로 보여주어야합니다. 페이지에 접근할 때 API를 호출한다면 컴포넌트 깜박임이 있을 수 밖에 없죠.

앱의 상황을 충분히 고려하여 라이켓 팀에서는 최종적으로 3번 방법으로 결정하였습니다.

프론트에서 JSON형태로 데이터를 보관하는 것이죠.

이제 태그 데이터는 앱을 다운로드하는 시점에서 보관하는 데이터가 될테니 더 이상 페이지가 로딩될 때 깜박이지는 않을 것입니다. 또한 API를 사용하는 것보다 훨씬 빠르게 로딩됩니다. 태그 데이터를 가져오기 위한 3-way-handshake를 하지 않아도 되니까요.


❓ 무엇을 포기하고 무엇을 얻었을까?

이 방식의 최대 단점은 태그 데이터를 두 번 관리해주어야 한다는 것입니다. 만약 장르 데이터가 추가된다면 어떻게 될까요? 백엔드에서는 테이블에 데이터를 넣어야하고 idxname을 프론트에게 알려주어 프론트에서도 가지고 있는 JSON 데이터를 변경해야합니다.

LIKET 팀에서는 이를 메뉴얼화하여 버전 업데이트 시 꼭 확인해야하는 사항에 넣었습니다. 태그 데이터를 변경하기 위해서는 반드시 태그 테이블프론트 JSON 데이터를 확인해야하도록 말이죠. 휴먼 에러를 방지하기 위함입니다.

태그 데이터를 다루기가 더욱 복잡해졌습니다. 그렇다면 얻은 것은 무엇일까요?

  1. 빠른 페이지 로딩
  2. 불필요한 API 호출 방지
  3. API 호출 코드 삭제로인한 프론트 코드 간결화

불필요한 API 호출을 막는 것은 트래픽 비용 절감까지도 이어질 수 있습니다. 서버와 통신할 것을 통신하지 않아도 되니까요. 페이지 로딩또한 더욱 빨라집니다. 통신을 기다릴 필요가 없으니까요!


⭐️ 결론

변경되는 기획사항에 맞춰 구현했던 기능을 변경했던 과정에 대해서 길게 이야기해보았습니다.

언제나 다양한 방법 속에서 장단점을 비교하고 구현하는 LIKET팀의 민경찬이였습니다.

감사합니다.

0개의 댓글