Skip to content
isdnetworks
Go back

상태 컬럼으로 센 잘못된 분류

(수정됨)

주문 상태별 건수를 내니 합이 전체와 맞아떨어져서 문제가 없어 보였다. 그런데 부분 취소된 주문이 몇 건이냐는 질문을 받고 답을 못 했다.

Table of contents

Open Table of contents

원인 — 상태가 못 담는 것

전체 취소는 orders.status로 표현되는데 부분 취소는 그것이 안 바뀌고 order_items.status에만 표시되고 있었다. order_items를 기준으로 EXISTS로 다시 세니 3천여 건이 부분 취소에 해당했다.

그 건들은 orders.status로 세면 결제 완료나 배송 완료에 섞여 있었다. 상태 컬럼 하나로는 담지 못하는 상태가 있고 그것을 모르면 집계가 조용히 틀린다.

판단 기준 — 무엇을 세는지의 정의

그래서 무엇을 세는지를 네 가지로 나눠 정의하고 각각 다른 조회로 만들었다. 결제 완료 주문과 전체 취소 주문과 부분 취소를 포함한 주문이다. 거기에 NOT EXISTS로 항목에 취소가 하나도 없는 정상 완료 주문이다.

전에는 취소라고만 하면 전체 취소만 세고 있었는데 정의를 나눈 뒤로는 어느 숫자를 묻는지가 질문 단계에서 분명해졌다.

결과 — 조합 판정이 드러낸 것

분류를 조합으로 판정하는 classify() 함수를 만들다가 예상에 없던 넷째 경우가 나왔다. order_items가 전부 'cancelled'인데 orders.status는 그대로 살아 있는 것이었다.

HAVING으로 세어 보니 수백 건이었고 항목을 취소할 때 주문 상태를 함께 보지 않는 코드가 원인이었다. 전부 취소되면 주문도 취소하도록 고치고 이미 그렇게 된 수백 건은 정산에 영향이 있어 확인받고 따로 처리했다. 분류하려고 조합을 따지다가 아무도 몰랐던 상태가 드러났다.

조치 — 저장과 대조

두 가지 방법이 있었는데 판정을 매번 계산하는 것과 cancel_class 컬럼에 저장하는 것이다. 통계용으로는 뒤쪽을 골랐다. 이유는 매번 계산하면 집계 조회가 무거워서다. 대신 갱신을 빠뜨렸을 때 틀린 값이 남는 위험을 감수했고 화면에서는 그때그때 계산하게 갈랐다.

저장한 cancel_class가 맞는지는 매일 계산값과 대조하는 조회를 cron으로 돌려 확인했다. 화면에도 결제 완료 안에서 정상과 부분 취소와 전 항목 취소를 나눠 보이게 하니 이상한 것이 바로 눈에 띄었다.

대안 — 축이 여럿인 것을 한 컬럼에

부분 취소를 상태값으로 하나 추가할 수도 있었지만 그렇게 하지 않았다. 부분 취소와 배송 완료가 겹치고 거기에 부분 환불까지 겹치면 조합이 곱해져 상태가 수십 개로 늘어난다.

주문의 진행 단계는 기존 status로 두고 취소 여부는 별도 cancel_class 컬럼으로 뒀다. 축이 여럿인 것을 한 컬럼에 담으려 하면 상태가 폭발하므로 축을 나누면 조합이 곱해져도 각각은 단순하다.

정리


Share this post on:

Previous Post
세 조건을 항상 같이 걸었다
Next Post
통계로 읽은 내 문제 기록