좋아요 정렬을 위한 핵심 데이터와 집계 데이터 분리
집계 분리, 명시적인 최신성 기준, 비동기 갱신, 정합성 보정, 검색 경계로 좋아요 기반 정렬을 확장합니다.
출처 및 AI 안내: 이 글은 제미니의 개발실무 유튜브를 기반으로 작성되었습니다.
gpt-5.6-sol모델을 사용해 생성·편집했습니다.
원본 좋아요 데이터로 전체 정렬하기 어려워지면 상품이나 리뷰의 핵심 행에 카운터를 넣기보다 별도 집계 테이블에 순위 신호를 둔다. 공개 개수가 얼마나 최신이어야 하는지 정하고, 좋아요 등록을 막지 않게 집계를 갱신하며, 제품이 납득할 주기로 정합성을 다시 맞춘다.
현재 페이지의 개수와 전체 정렬은 다른 문제다
그룹 집계로 목록에 좋아요 수를 표시할 수 있다. 전체 상품을 좋아요순으로 정렬하려면 페이지를 자르기 전에 모든 후보를 비교해야 한다. 데이터가 커지면 원본 반응을 매번 전부 그룹 집계하기 어렵고, 무거운 쿼리를 캐시로 감싸도 만료 순간 요청이 몰릴 수 있다.
집계 테이블은 상품이나 리뷰마다 한 행만 둬 작업 집합을 줄인다. like_count뿐 아니라 리뷰 수나 평점처럼 순위에 필요한 값을 함께 둘 수 있다. 작은 집계 구조에서 정렬해 페이지 아이디를 얻은 뒤 핵심 데이터를 조회한다.
집계의 생명주기를 핵심 데이터와 나눈다
상품이나 리뷰가 화면과 검색에 쓰는 모든 파생 통계를 소유할 필요는 없다. 그런 통계는 그 값이 없어도 존재하는 핵심 개념에 부가 순위 책임을 섞는다.
별도 테이블은 집계가 핵심 개념과 다른 생명주기를 가질 수 있음을 드러낸다. 절대 규칙은 아니다. PO나 기획자가 그 숫자를 충분히 중요하게 본다면 중심 행에 저장하는 편이 맞을 수도 있다.
최신성은 사용자 가치에 따라 다르게 산다
사용자가 좋아요나 찜을 누른 뒤 자기 목록에서 바로 확인하는 경험은 즉시성이 필요할 수 있다. 상품 옆의 공개 개수는 조금 늦어도 괜찮을 수 있다. 서로 다른 정합성 약속에 같은 비용을 쓸 이유는 없다.
집계는 정기 배치로 다시 만들거나 일정 주기로 갱신하거나 준실시간으로 유지할 수 있다. 트렌드에 민감한 제품은 짧은 간격이 필요하고 순위가 천천히 바뀌는 곳은 더 길어도 된다. 트래픽과 최신성 요구가 방식을 정해야지 예시 숫자와 주기를 보편 기준으로 삼아서는 안 된다.
집계 경합을 핵심 행위에서 격리한다
좋아요를 기록하는 트랜잭션 안에서 인기 상품의 집계 행까지 올리면 부가 행의 경합 때문에 사용자의 좋아요가 실패할 수 있다. 최종 일관성을 허용한다면 같은 트랜잭션에서 집계 행을 갱신하지 않고, 좋아요를 기록한 뒤 집계를 비동기로 처리한다.
규모가 크지 않다면 애플리케이션의 비동기 작업으로 충분할 수 있다. 이벤트가 많아지면 발행과 소비를 분리해 처리량을 조절할 수 있다. 비동기 집계에서는 정합성이 깨질 수 있으므로 그 차이가 치명적인지, 주기적으로 동기화해도 괜찮은 서비스인지 판단한다.
복합 정렬은 검색 경계로 발전할 수 있다
정렬에 개인화, 색상, 계절, 평점 같은 신호가 계속 붙으면 일반 도메인 조회보다 검색에 가까워진다. 깨끗한 메타데이터 공급 경계를 두면 핵심 DB가 모든 쿼리 모양을 떠안지 않고 나중에 검색 서비스를 분리할 수 있다.
검색 시스템은 정렬된 아이디를 반환하고 서비스는 데이터베이스에서 상세를 읽을 수 있다. 단순 정렬만 필요한 작은 서비스에 처음부터 이 구조를 두면 과하다. 그룹 쿼리로 시작하고, 데이터가 많아 전역 정렬이 어려워지면 별도 집계로 옮기며, 서비스가 커져 검색 요구가 분명해질 때 전용 검색을 도입한다. 현재 트래픽과 규모, 요구사항에 맞는 단계를 고른다.