✅reservation.arrival_date_dt (Generated Column + Index) 적용 체크리스트

YEONGHUN KO·2026년 2월 5일

BACKEND - DATABASE

목록 보기
9/9

목표

  • arrival_date(문자열 'YYYY. MM. DD.')는 그대로 유지
  • 검색/집계 성능을 위해 arrival_date_dt(DATE) 파생 컬럼을 DB가 자동 생성하도록 추가
  • arrival_date_dt 인덱스로 월별/기간 필터링을 빠르게 만들기

0) 적용 전 이해 (한 줄)

  • arrival_date_dtINSERT/UPDATE 시 DB가 자동 계산해서 저장(STORED)됨
  • 앱에서 arrival_date_dt를 직접 넣거나 수정할 필요/권한 없음

1) 사전 점검

1-1. 포맷이 100% 고정인지 확인 (깨진 데이터가 있으면 dt가 NULL 될 수 있음)

SELECT COUNT(*) AS bad_cnt
FROM reservation
WHERE arrival_date IS NOT NULL
  AND arrival_date NOT REGEXP '^[0-9]{4}\\. [0-9]{2}\\. [0-9]{2}\\.$';


selectPartnerProducts7MonthsRevenue: () => {
  let query = `
    WITH RECURSIVE months AS (
      SELECT DATE_SUB(DATE_FORMAT(?, '%Y-%m-01'), INTERVAL 1 MONTH) AS month_start, 0 AS n
      UNION ALL
      SELECT DATE_ADD(month_start, INTERVAL 1 MONTH), n + 1
      FROM months
      WHERE n < 7
    )
    SELECT
      DATE_FORMAT(m.month_start, '%Y-%m') AS ym,
      COALESCE(COUNT(r.reservation_no), 0) AS total_cnt,
      COALESCE(SUM(r.final_payment_local), 0) AS revenue_sum
    FROM months m
    LEFT JOIN reservation r
      ON r.arrival_date_dt >= m.month_start
     AND r.arrival_date_dt <  DATE_ADD(m.month_start, INTERVAL 1 MONTH)
     AND NOT (r.status = 3 AND COALESCE(r.refunded_jpy, 0) > 0)
    LEFT JOIN product p
      ON p.product_id = r.product_id
     AND p.owner_user_no = ?
    -- ✅ 월이 비어있는 row( r=NULL )는 살리고
    -- ✅ r이 있으면 반드시 p(owner 일치)가 있는 것만 남김
    WHERE r.reservation_no IS NULL OR p.product_id IS NOT NULL
    GROUP BY m.month_start
    ORDER BY m.month_start;
  `;
  return query;
},

////...../////
params = [anchorDate, ownerUserNo];
profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글