본문 바로가기

카테고리 없음

구독 테이블 설계하기

 

요즘 구독 테이블 설계를 하고 있다.

이미 만들어져있는 구독 서비스를 유지보수 해본 적은 있지만 구독 테이블을 직접 설계하는건 처음이다.

고민했던 2가지 주제를 공유하고자 한다.

 

주제 1) 구독 테이블 설계 - 한 줄로 관리할 것인가, 매 월 새로운 행을 추가할 것인가?

구독 테이블 관리 방식에 관한 얘기이다.

 

(1) 한 개의 row 를 유지하며 갱신하는 방식

- 유저가 특정 플랜을 구독하면 subscription 테이블에 한 개의 row 가 INSERT 됨

- 매달 결제가 이루어질 때 currentPeriodStart, currentPeriodEnd 를 업데이트하여 현재 구독 기간을 관리

- 결제 내역 테이블 (paymentHistory) 을  subscription 과 1:N 관계로 두어, 매달 결제가 이루어질 때 새로운 결제 내역을 INSERT 함

 

 

(2) 매월 새로운 row 를 INSERT 하는 방식

- 매월 구독이 갱신될 때마다 새로운 row 를 INSERT 하며 각 row 는 특정 월의 구독을 나타냄

 

이 방식은 "데이터 중복" 의 특성을 가지고 있기 때문에 맞지 않다고 판단했다. 이유는 아래와 같다.

1) 동일한 구독 정보가 매월 새로운 row 로 삽입되므로 데이터가 불필요하게 많아질 수 있음

2) 데이터 조회 패턴의 빈도 측면에서 보자면 사용자가 "구독 이력" 을 보는 화면은 존재하지 않음 

대신 결제 내역만 존재하니까 그건 paymentHistory 테이블만 조회화면 됨

 

 

주제 2 ) 구독 플랜에 대한 무료체험 정보는 어디에 기록해야 할까?

보통 요금제가 있는 서비스들을 보면 구독을 하면 처음에 무료체험을 주는 경우가 있다. 

이 무료체험의 정보는 어디다가 저장해야하는 가에 관한 얘기이다.

 

 

(1) subscription 테이블에 무료체험 기간 관련 컬럼 추가

처음에는 무료체험 정보를 구독 테이블에 직접 추가해야 한다고 판단했다.

기존 구독 정보와 무료 체험 기간을 같은 row 에서 관리할 수 있어 조회가 용이하기 때문이다.

 

 

(2) 무료체험 정보를 별도 테이블로 분리해서 저장하기

하지만, 무료체험 정보가 subscription 테이블에 포함되는 것이 낭비일 수도 있다.

무료체험을 제공하지 않는 플랜의 경우 trialStart, trialEnd 컬럼이 의미 없이 NULL 이 되어 공간 낭비가 발생할 수 있고

nullable 필드가 생기면 로직에서 매번 타입 체크를 해야 하므로 코드 복잡성이 증가하기 때문이다.

 

 

조회 패턴을 고려했을 때, 유저의 무료체험 여부를 빠르게 조회해야 할 일이 많다.

subscription 테이블에 직접 저장하는 방식 trialHistory 테이블로 분리하는 방식 모두 조회 속도에는 큰 차이가 없었으나

코드 복잡성을 그나마 줄일 수 있는 trialHistory 테이블을 별도로 두는 방식이 더 적합하다고 판단했다.