주문 시 가격 저장으로 과거 데이터 신뢰성 확보하기

2025. 2. 24.

주문 시 가격 저장으로 과거 데이터 신뢰성 확보하기

개요

테이블 오더 시스템에서는 메뉴나 옵션 가격이 바뀌었을 때 과거 주문 데이터까지 변해버리는 문제가 발생할 수 있습니다.
이 글에서는 주문 시점에 가격을 저장하여 과거 거래 데이터를 안전하게 보존하고, 데이터 신뢰성을 유지하는 방법을 소개합니다.


문제 상황: 가격 변경으로 생기는 혼란

"사장님, 저번에 이거 7,000원이었는데 오늘은 왜 7,500원이죠?"

POS 시스템을 열어보니 메뉴 가격이 정말 변경되어 있던 경험, 한 번쯤 있으시죠?
이런 문제는 대부분 메뉴 및 옵션 가격을 주문 시점에 실시간 조회하는 구조 때문에 발생합니다.


실시간 가격 조회의 한계

테이블 오더 시스템을 처음 설계할 때는, 주문 시 DB에서 메뉴와 옵션 가격을 실시간으로 조회하는 방식을 쉽게 떠올릴 수 있습니다.
하지만 이 구조에는 치명적인 문제가 숨어 있습니다.

  • 메뉴나 옵션 가격이 변경되면,
  • 과거 주문 기록까지 새 가격으로 덮어쓰기 됩니다.

이로 인해:

  • 과거 주문 금액을 정확히 확인할 수 없고,
  • 환불 및 클레임 처리도 힘들어지며,
  • 시스템 전체에 대한 신뢰가 떨어집니다.

거래 기록은 변해서는 안 됩니다.
이 원칙이 무너지면, 고객 불신은 물론이고 법적 문제까지 이어질 수 있습니다.


해결 방법: 주문 시점 가격 저장하기

답은 간단합니다. 주문 생성 시 가격을 저장하면 됩니다.
구체적으로는 다음 정보를 별도로 기록해야 합니다.

  • 메뉴 가격 (price)
  • 옵션 가격 (option_price)

이렇게 하면, 이후 메뉴나 옵션 가격이 아무리 변경되어도 과거 주문 내역은 변하지 않습니다.


PostgreSQL 테이블 설계 예시

주문 시 가격 저장을 위해 테이블을 이렇게 구성할 수 있습니다.

주문 아이템 테이블 (order_items)

컬럼명 타입 설명
id SERIAL 기본 키
order_id INTEGER 주문 ID
menu_id VARCHAR 메뉴 ID
quantity INTEGER 수량
price NUMERIC(10,2) 주문 당시 메뉴 가격

주문 아이템 옵션 테이블 (order_item_options)

컬럼명 타입 설명
id SERIAL 기본 키
order_item_id INTEGER 주문 아이템 ID
option_id VARCHAR 옵션 ID
option_price NUMERIC(10,2) 주문 당시 옵션 가격

💬 팁: 금액 데이터는 NUMERIC(10,2) 타입을 사용해야 부동소수점 오차 없이 안전하게 다룰 수 있습니다.


주문 총액 계산 쿼리 작성하기

가격을 저장했다면, 주문별 총액은 이렇게 간단히 계산할 수 있습니다.

SELECT
  SUM(oi.price * oi.quantity) + COALESCE(SUM(oio.option_price), 0) AS total_price
FROM order_items oi
LEFT JOIN order_item_options oio ON oi.id = oio.order_item_id
WHERE oi.order_id = 101;

  • COALESCE를 사용해 옵션이 없는 경우에도 0으로 처리합니다.
  • 상황에 따라 GROUP BY를 추가할 수 있습니다.

PostgreSQL 버전에 따라 JOIN 및 SUM 연산 최적화 방식은 다를 수 있습니다.


기대할 수 있는 효과

  • 과거 주문 내역이 가격 변경에 영향을 받지 않습니다.
  • 환불, 증빙, 고객 문의 대응이 쉬워집니다.
  • 메뉴 가격이 바뀌어도 시스템이 문제없이 작동합니다.

개발 시 유의사항

  1. 주문 생성 시 가격을 반드시 저장해야 합니다.
  2. 총 금액 계산은 저장된 가격을 기준으로 해야 합니다.
  3. 프론트엔드와 백엔드 모두 이 원칙을 이해하고 일관성 있게 구현해야 합니다.

거래 데이터는 시간이 지나도 변하지 않아야 합니다.
변하는 데이터는 신뢰를 잃습니다.