본문으로 건너뛰기
유환호 연락하기

홈 / 기록

운영 DB는 30일 뒤 지운다 — 리포트를 얼려야 하는 이유

한눈에 답변

체험단 운영 테이블은 마감 30일 뒤 행을 지운다. 월간 리포트를 만들 때 '지금 데이터가 많이 남아 있다'를 완전성의 근거로 삼는 건 착각이다 — 실제로 8월 1~2일 발견분 중 약 115건(0.66%)이 이미 삭제됐을 것으로 역산됐다. 이후 삭제되기 전에 영구 보존하는 별도 테이블을 새로 만들었다.

리뷰로거에 월간 데이터 리포트를 만들기로 했다. “2026년 8월 한 달간 수집한 공고 통계”를 내는 일이다. 착수 전에 DB를 확인했다 — campaigns 테이블은 사용자에게 실시간으로 보여주는 운영 테이블이고, cleanup.mjs 스크립트가 마감 지난 지 30일 된 공고를 지운다.

“많이 남아 있다”는 완전성의 증거가 아니다

처음엔 테이블에 23,246행(그중 마감된 것 18,348행)이 있으니 8월 리포트가 성립한다고 판단했다. 그런데 이건 틀린 논리였다 — 데이터가 많이 남아 있다는 것과, 그 달의 데이터가 전부 남아 있다는 것은 다른 말이다. cleanup 이 30일 지난 것부터 지우므로, 집계 시점이 늦어질수록 그 달의 앞부분부터 사라진다.

얼마나 지워졌는지 역산했다

지워진 행은 셀 수 없다. 대신 삭제 영향이 없는 날(발견일 자체가 삭제선 이후인 날)의 ‘발견→마감’ 기간 분포를 기준으로 역산했다. 발견일 D 의 공고가 지워지려면 마감까지 남은 기간 ≤ 삭제선 − D 여야 하므로, 그 조건에 해당하는 비율을 안전한 날들에서 구하고 생존 수 ÷ (1 − 그 비율) 로 원래 수를 추정하는 방식이다.

8월 1일 발견분: 생존 870건, 추정 소실 약 106건. 8월 2일: 생존 183건, 추정 소실 약 9건. 8월 3일부터는 삭제선 이후라 영향이 없었다. 합계 약 115건, 관측치의 0.66%.

다음 달부터는 지워지지 않게

이번엔 추정으로 넘어갔지만, 매달 같은 문제를 반복할 수는 없었다. 그래서 삭제되기 전에 공고를 한 줄씩 영구 보존하는 별도 테이블을 새로 설계했다. 이벤트 로그처럼 매 수집마다 행을 쌓는 방식은 아니다 — 공고 하나당 한 행을 유지하며, 시간에 따라 변하는 신청자 수만 최초값·최종값·최댓값 세 개로 압축해 남긴다. 그래야 “마감에 가까운 경쟁률”도 나중에 계산할 수 있다.

리포트에 그대로 적었다

이 소실 추정치를 리포트 안에 감추지 않고 그대로 실었다 — “이미 삭제된 공고는 약 115건(0.66%)으로 추정됩니다”라고. 정확한 숫자를 모른다는 사실 자체가, 이 통계가 무엇을 재는지에 대한 정보다.