Playball Logo

Command Palette

Search for a command to run...

목차 열기

추천 알고리즘

PlayBall의 추천 서비스는 일반 티켓팅 사이트와 차별화된 핵심 기능입니다. 유저가 직접 좌석맵에서 좌석을 고르는 대신, 온보딩 시 입력한 선호 데이터를 기반으로 최적의 블럭을 1순위~10순위로 추천하고, 블럭을 선택하면 서버가 자동으로 최적 연석을 배정합니다. 추천 시스템은 블록 추천(Phase 1)좌석 배정(Phase 2) 두 단계로 나뉩니다.


온보딩 선호 데이터

회원가입 직후 온보딩 과정에서 다음 데이터를 수집합니다.

데이터엔티티추천 알고리즘 사용
선호 구단OnboardingPreference.favoriteClub1루/3루 블럭 방향 결정
응원석 인접 선호cheerProximityPref (NEAR/FAR/ANY)응원석 근접 블럭 가산점
뷰포인트 우선순위OnboardingViewpointPriority (1~3순위)뷰포인트 매칭 가산점
선호 블럭 목록OnboardingPreferredBlock추천 대상 블럭 필터링

구단 기반 1루/3루 자동 판정

경기: 삼성 라이온즈 vs 한화 이글스
유저 선호 구단: 삼성 라이온즈

Case 1: 삼성이 홈(1루)일 때    → 1루(홈) 블럭 쪽 추천 가산점 +25점
Case 2: 삼성이 어웨이(3루)일 때 → 3루(어웨이) 블럭 쪽 추천 가산점 +25점
Case 3: 삼성이 참여하지 않는 경기 → 뷰포인트 우선순위로 판정

Phase 1 — 블록 추천

선호 블록(최대 10개)만 탐색하여 실제 N연석이 가능한 묶음 수를 계산하고, 취향 점수를 매깁니다.

취향 점수 계산 (최대 70점)

항목조건점수
뷰포인트 우선순위1순위 블록30점
뷰포인트 우선순위2순위 블록20점
뷰포인트 우선순위3순위 블록10점
응원구단 매칭경기 참가 구단 선호 + 블럭 진영 일치+25점
응원석 근접 (NEAR)NEAR 선호 + cheerRank ≤ 3+15점
응원석 원거리 (FAR)FAR 선호 + cheerRank > 3+15점

정렬 기준

  1. 1차: 가용 연석 수 (차이가 10석 초과 시 바로 결정)
  2. 2차: 연석 수 차이 ≤ 10 → 취향 점수 높은 순
  3. 3차: 동점 시 → 연석 개수 순
예시 (N=4명 요청):

블럭 A: 연석 42개, 선호도 65점
블럭 B: 연석 38개, 선호도 55점
블럭 C: 연석 40개, 선호도 70점

A vs C: |42-40| = 2 ≤ 10 → 선호도 비교 → C(70) > A(65) → C가 상위
A vs B: |42-38| = 4 ≤ 10 → 선호도 비교 → A(65) > B(55) → A가 상위
최종: C(1순위) → A(2순위) → B(3순위)

만약 블럭 D: 연석 5개, 선호도 70점이라면
A vs D: |42-5| = 37 > 10 → 연석 수 비교 → A가 상위
(선호도가 아무리 높아도 좌석이 너무 적으면 하위 랭크)

Phase 2 — 좌석 배정

사용자가 블록을 선택하면 Redisson 블럭 단위 분산 락을 획득하고, 실연석(같은 열 연속 N석) → 준연석(인접 2열 N석) 순으로 탐색합니다.

배정 우선순위

  1. 실연석 (Real Consecutive) — 같은 행의 연속 좌석
    • Priority 1: 앞줄 (rowNo 오름차순)
    • Priority 2: 통로 근접 (aisleDistance 오름차순)
    • Priority 3: 왼쪽 (startCol 오름차순)
  2. 준연석 (Semi-Consecutive) — 인접 2행 겹침 (인접석 토글 ON 시)
    • 두 행이 물리적으로 인접 (rowNo 차이 = 1)
    • 수평 겹침(overlap) > 0 필수
    • Priority: 앞줄 합 → 겹침 수 최대 → 평균 통로 근접
  3. 준연석도 없는 경우 — 추천 좌석 없음 반환

통로 근접도 (Aisle Distance) 계산

rowStartCol = 해당 열의 첫 번째 좌석 열번호
rowEndCol = 해당 열의 마지막 좌석 열번호

leftDistance = groupStartCol - rowStartCol   (왼쪽 통로까지 거리)
rightDistance = rowEndCol - groupEndCol       (오른쪽 통로까지 거리)

aisleDistance = min(leftDistance, rightDistance)

동시성 제어 (조건부 UPDATE)

좌석 상태 변경 시 markBlockedIfAvailable() 조건부 UPDATE로 일반 좌석 선택 모드와의 충돌까지 안전하게 감지합니다. 실연석/준연석 각각 최대 3회 재시도로 다른 연석 구간을 탐색합니다.

UPDATE match_seats
SET sale_status = 'BLOCKED'
WHERE id = :matchSeatId
  AND sale_status = 'AVAILABLE'
-- return 0이면 이미 다른 유저가 선점 → 롤백 후 재시도

배정된 좌석은 5분간 Hold 상태가 되며, 만료 시 SeatHoldCleanupScheduler에 의해 60초 간격으로 자동 해제됩니다.


추천 ON vs 추천 OFF

항목추천 ON추천 OFF (일반 선택)
블럭 선택서버가 추천 (1~10순위)유저가 직접 선택
좌석 배정서버가 자동 배정 (연석)유저가 좌석맵에서 직접 클릭
락 단위블럭 단위 Redisson RLock (Watch Dog)좌석 단위 Redisson RLock (500ms wait)
인원수예매 옵션에서 사전 설정클릭한 좌석 수 = 인원수