본문 바로가기
IT 서비스/주문 관리 플랫폼

[ 리뷰 기능 ] 매장 평균 별점 기능 고도화하기 - 1

by agong이 2025. 2. 20.

📜서론

단순히 매장 목록을 조회할때 해당 매장의 평균 별점까지 함께 제공하려면 성능 이슈가 발생할 수 있습니다. 이번 글에서는 어떤 방법들이 있고 제가 선택한 해결 방법을 작성하려고 합니다.

 

문제 상황

사용자가 매장 목록을 조회할 때, 단순히 매장 정보만 불러오는 것이 아니라 해당 매장의 평균 별점도 함께 보여줘야 합니다. 이를 위해 기본적인 접근 방식은 다음과 같습니다.

  1. 매장 목록을 불러올 때, 각 매장의 리뷰를 모두 조회합니다.
  2. 해당 리뷰들의 별점을 가져와 평균을 계산합니다.
  3. 계산된 평균 별점을 매장 목록과 함께 사용자에게 제공합니다.
// 매징들의 평균 별점을 한번에 조회
    @Query("SELECT r.store.id, AVG(r.rating) FROM Review r WHERE r.store.id IN :storeIds GROUP BY r.store.id")
    List<Object[]> findAverageRatingsByStoreIdList(@Param("storeIds") List<Long> storeIds);

 

이 방식은 단순하지만 치명적인 문제가 있습니다.

 

성능 문제 발생

  • 데이터베이스 부하
    • 매장 목록을 조회할 때마다 매장의 리뷰를 모두 조회해야 합니다.
    • 리뷰가 많아질수록 조회 쿼리의 부하가 증가하고 응답 속도가 느려집니다.
  • 연산량 증가
    • 매 요청마다 평균 별점을 계산하면 불필요한 연산이 반복됩니다. 
    • 사용자가 많아지면 데이터베이스에 큰 부하가 발생합니다.

정리하자면 매장이 많고 리뷰가 계속 쌓이면 성능 저하가 심화됩니다. 서비스가 성장할수록 더욱 비효율적인 구조가 됩니다. 따라서, 평균 별점 계산을 효율적으로 처리할 방법이 필요합니다.

 

🤔해결 방법

1. Store 테이블에 avg 컬럼 추가

  • 매장 테이블(Store)에 별점 평균을 저장하는 avg_rating 컬럼을 추가합니다.
  • 새로운 리뷰가 추가될 때마다 별점 평균을 다시 계산하여 이 컬럼을 업데이트합니다.

장점
✅ 매장 목록 조회 시 별점을 바로 제공할 수 있어 빠름.
✅ 평균 별점을 계산하는 추가적인 연산 없이 조회 속도가 향상됨.

단점
❌ 리뷰가 추가될 때마다 avg_rating을 업데이트해야 하므로 트랜잭션이 많아질 수 있음.

 

 

2. Store 테이블에 avg 컬럼 추가 + 스케줄러를 활용한 주기적 갱신

  • 1번의 단점을 해결하기 위한 방법으로, 일정한 주기로 평균 별점을 갱신합니다.
  • 예를 들어, 1시간 단위로 배치 작업을 실행하여 avg_rating을 업데이트합니다.

장점
✅ 실시간 업데이트 부담이 줄어들어 성능이 개선됨.
✅ 트랜잭션 충돌 가능성이 낮아짐.

단점
❌ 별점이 즉시 반영되지 않아 사용자 경험이 떨어질 수 있음.
❌ 실시간 성이 떨어짐.

 

3. Redis를 활용한 캐싱

  • 별점 평균을 자주 조회하지만 자주 변경되지는 않기 때문에 Redis에 캐싱하는 방법을 고려할 수 있습니다.
  • 사용자가 매장 목록을 조회할 때 Redis에서 바로 평균 별점을 가져와 빠르게 응답합니다.
  • 새로운 리뷰가 추가되거나 업데이트될 때 Redis의 평균 별점 데이터를 갱신하여 최신 상태를 유지합니다.

장점
✅ 조회 속도가 매우 빠름.
✅ 데이터베이스 부하를 줄일 수 있음.

단점
별도의 Redis 서버를 구축해야 함. (현재 다른 기능에서는 Redis를 사용하고 있지 않습니다.)
❌ 별점이 갱신될 때마다 Redis를 업데이트해야 하는 관리 비용이 발생함.

 

4. 스케줄러 + Redis 병행 활용

  • 스케줄러를 활용하여 주기적으로 평균 별점을 갱신하면서, Redis를 통해 빠르게 응답하도록 설계할 수 있습니다.
  • 리뷰가 추가될 때마다 Redis에서 평균 별점을 즉시 업데이트합니다.
  • 장기적으로는 스케줄러가 주기적으로 Redis의 데이터를 최신 상태로 유지합니다.

장점
✅ 3번의 장점과 함께 댓글이 갱신될 때마다 Redis를 업데이트해야 하는 관리 비용을 줄일 수 있음.
✅ 데이터베이스 부하를 효과적으로 줄일 수 있음.

단점
❌실시간성이 떨어짐.
❌ Redis와 데이터베이스 간 동기화 과정에서 일관성을 유지해야 함.

 

 

 

 

 

👆선택한 방법

저희 서비스에서는 현재 Redis를 사용하지 않기 때문에 별도로 Redis 서버를 구축하는 것은 다소 과하다고 판단했습니다. 따라서 4번 방법인 'Reids와 스케줄러를 활용한 주기적 갱신'을 선택했습니다. 이 방법은 빠르게 데이터를 조회할 수 있고 데이터베이스의 부하가 가장적기 때문에 서비스의 확장성을 고려하여 해당 방법을 선택하였습니다. 수 있는 장점이 있습니다.

 

댓글