민프

[DB] 실무에서 중간 테이블을 도입해야 하는 이유 – Payments(결제) 사례로 배우는 RDB 설계 본문

Backend/[DB]

[DB] 실무에서 중간 테이블을 도입해야 하는 이유 – Payments(결제) 사례로 배우는 RDB 설계

민프야 2025. 4. 17. 10:55

요즘 프로젝트를 진행하면서 한 가지 중요한 DB 설계 포인트를 마주했다. 

바로 “결제(Payments)와 주문(Orders)의 관계를 어떻게 정의할 것인가?” 였다. 

 

처음엔 단순했다. 결제는 주문을 하나 처리하면 되겠지 싶었다. 

하지만, 실제 비즈니스 요구사항이 점점 늘어나면서 단일 필드로 연결하는 방식의 한계를 절실히 느꼈다. 

그래서 도입하게 된 게 바로 중간 테이블(Bridge Table, Mapping Table) 이다. 

 

오늘은 그 이유와 실전 적용 과정을 실제 테이블 설계 예시를 통해 소개한다.

 


문제 정의 - 하나의 결제에 여러 주문?

예시

payments (table)
- payment_id (PK)
- order_id (FK)

 

payments 테이블에서 order_id를 외래키로 직접 참조하는 방식이다.

 

이 방식의 전제는 단 하나

“결제는 항상 하나의 주문만 결제한다.”

 

그런데 현실은?

  • 💼 POS에서는 장바구니 여러 주문을 한 번에 결제
  • 🍽️ 테이블별 주문을 묶어 결제
  • 📦 키오스크에서 배달 주문을 한 번에 결제
  • 💰 결제 1건 → 주문 N건 연결 필요

 

이런 순간, 기존 설계로는 답이 없다.

우리는 DB 정규화를 무너뜨릴 수 없는 상황에서 새로운 해결책이 필요했다.


해결책 - 중간 테이블 도입

payment_order_products_map
- payment_id (FK → payments)
- order_id (FK → orders)

구조를 아래와 같이 바꿨다. 

 

테이블 설명
payments 결제 정보 (결제 상태, 수단, 총 금액 등)
orders 실제 주문 내역 (상품, 수량, 가격 등)
payment_order_products_map 결제-주문 간 N:N 관계를 중간에서 연결

 


왜 이 구조가 좋은가?

1. N:N 관계 표현이 명확해진다

  • 하나의 결제에 여러 주문을 연결
  • 하나의 주문이 여러 결제에 나눠질 수도 있음 (분할 결제 가능)

예시 

payment_id order_product_id
1 101
1 102
2 103

 

 

2. 유지보수가 쉬워진다

  • 로직 변경 없이 여러 주문 묶기 가능
  • 결제 취소/환불/재결제 로직을 더 유연하게 처리 가능
    (취소, 환불에 유연하게 되는게 좋은 것 같습니다.)

3. SQL JOIN이 간단해진다

SELECT *
FROM payments p
JOIN payment_order_products_map pop ON p.payment_id = pop.payment_id
JOIN orders o ON o.order_id = pop.order_id
WHERE p.payment_status = 'success';

이처럼 중간 테이블을 기준으로 결제-주문을 쉽게 JOIN할 수 있습니다. 

 

4. 정산, 리포트, 통계 처리에 강력하다

  • 월별 결제 건당 주문 집계
  • 주문별 결제 내역 추적
  • 할인 금액, 환불 금액 정확한 매핑 가능

🤔 그럼 order_id에 배열을 넣으면 되지 않나요?

단순하게 payments테이블 안에 order_id를 리스트로 넣으려고 했었는데, 생각해보면 이건 완전 비추인 방법이다.

 

  • RDB는 정규화를 기반으로 설계됨
  • order_id = '1,2,3' 같은 구조는 검색, 조인, 무결성 검증 불가
  • NoSQL이라면 괜찮지만 RDB에서는 JOIN 기반 쿼리 최적화 불가능

즉, 배열이나 리스트는 테이블로 풀어야 한다!


결론

중간 테이블을 추가한다는 건 테이블이 하나 더 생기는 것처럼 보이지만,

실제로는 복잡도를 줄이고 시스템 확장을 가능하게 하는 결정이다.

 

항상 내가 개발을 하면서 느끼는 부분을 이야기하며 마무리 하겠습니다. 

“당장은 불필요해 보여도, 내일의 기능을 위한 설계는 오늘부터 준비해야 한다.”

 

Comments