매번 기록을 쌓는 대신 세 값으로 압축해서 보존했다
한눈에 답변
공고 데이터를 영구 보존하는 별도 테이블을 만들면서, 시간에 따라 계속 바뀌는 신청자 수를 매번 새 행으로 쌓는 방식은 쓰지 않기로 했다. 그렇게 하면 연간 백만 행이 넘어가는데 그만한 분석 가치가 없었다. 대신 처음 관측값, 마지막 관측값, 최댓값 세 가지만 남기는 방식을 택했고, 이 값들을 안전하게 갱신하기 위해 별도의 데이터베이스 함수를 새로 만들었다.
왜 별도의 보존 테이블이 필요했나
운영 데이터베이스는 마감 30일이 지난 공고를 지우는 구조라 별도의 기록 보관소가 없다. 나중에 데이터 완전성을 확인하거나 과거를 되짚어 보려면, 지워지기 전에 어딘가에 별도로 남겨 둬야 했다.
왜 매번 행을 쌓는 방식을 쓰지 않았나
공고 하나의 신청자 수는 시간이 지나며 계속 바뀐다. 이 변화를 전부 기록으로 남기려면 매 수집 주기마다 새 행을 추가하는 방식(사건을 그대로 기록하는 방식)을 쓸 수 있다. 하지만 하루에도 몇 번씩 도는 수집 주기를 감안하면 이 방식은 연간 백만 행 단위로 불어난다. 그 정도로 촘촘한 기록이 실제로 분석에 필요한지 따져 보니, 그만한 가치가 없다고 판단했다.
대신 어떤 방식을 택했나
시간에 따라 변하는 값 하나를 처음 관측값, 마지막 관측값, 최댓값이라는 세 개의 숫자로 압축해서 남기기로 했다. 예를 들어 “마감에 가까울수록 치열해지는 경쟁률”이 궁금하다면 최댓값으로 계산할 수 있다. 공고 하나당 정확히 한 행만 남기는 구조라 규모도 훨씬 작아진다.
갱신 방식에서 무엇이 어려웠나
기존에 쓰던 데이터 갱신 방식으로는 “기존 값과 새 값 중 더 큰 쪽을 남긴다”거나 “관측 횟수를 1씩 늘린다” 같은 조건부 갱신을 표현할 수 없었다. 그래서 이 로직을 데이터베이스 함수로 만들어 여러 건을 한 번에 처리하도록 했다.
실행 순서에서 어떤 함정이 있었나
수집 작업 안에서 보존 처리와 만료 삭제 처리 중 어느 것을 먼저 실행하느냐가 중요했다. 삭제를 먼저 하면 그 회차에 지워질 공고가 보존 테이블에 반영되기도 전에 사라져 버린다. 반드시 보존을 먼저 하고 삭제를 나중에 해야 했다. 그리고 보존 테이블 자체가 아직 준비되지 않은 상황이라도, 그 이유로 전체 수집 작업이 중단되지 않도록 경고만 남기고 계속 진행하게 만들었다 — 보존이 안 됐다고 해서 당장의 서비스 운영까지 멈출 이유는 없기 때문이다.