본문 바로가기

카테고리 없음

구독 테이블 설계 (+ 무료체험)

 

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

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

이 과정에서 동료와 의견 차이가 있어서 그 과정을 기록하고자 한다.

총 2가지 논제가 있었다.

 

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

구독 시스템을 설계하는 과정에서 동료 개발자와 구독 테이블 관리 방식에 대해 의견 차이가 있었다.

 

📌 나의 주장 - 한 개의 row 를 유지하며 갱신하는 방식

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

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

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

 

 

📌 동료의 주장 - 매월 새로운 row 를 INSERT 하는 방식

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

 

 

나는 동료의 주장이 "데이터 중복" 의 특성을 가지고 있기 때문에 반대했다.

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

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

"현재 활성화된 구독 정보 (ex. Premium 이용 중입니다)" 를 조회하는 화면만 있기 때문에 나의 주장이 맞다고 판단했다.

 구독 이력을 보고 싶은 케이스가 생긴다면 결제 내역 테이블이 존재하므로 충분히 쿼리를 통해 뽑아낼 수 있다고 판단했다.

그래서 나의 주장을 채택하기로 했다.

 

 

 

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

보통 요금제가 있는 서비스들을 보면 구독 플랜에 7일 무료체험이 존재한다.

나는 이 무료체험 정보를 subscription 테이블에 넣어야한다고 판단했다.

 

 

📌 나의 주장: subscription 테이블에 trialStart, trialEnd 컬럼 추가

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

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

 

 

📌 동료의 주장: 무료체험 정보를 별도 테이블로 분리해야 한다

동료는 무료체험 정보가 subscription 테이블에 포함되는 것이 낭비라고 주장했다.

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

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

 

 

결론적으로 동료의 방식을 채택하기로 했다.

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

내가 주장했던 subscription 테이블에 직접 저장하는 방식 trialHistory 테이블로 분리하는 방식 모두 조회 속도에는 큰 차이가 없었다.

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