프로젝트를 진행하며 우리 서비스에 맞는 데이터 스키마는 무엇일지 고민한 과정을 기록해봤다.
나는 매일 저녁 런닝을 뛰면서 GPT와 함께 면접 연습을 한다. 프롬포트로 나에 대한 정보와 내 대답에 맞는 꼬리 질문을 생성하게 하여 연습하는데 이를 웹 프로젝트로 구현하면 어떨까 라는 생각에서 우리 프로젝트는 시작됐다.
프로젝트의 핵심 기능은 AI와 혼자 연습하기
, 사람과 1대1로 연습하기
, 면접 질문 세트 공유
3가지이고, 이 글에서 다룰 것은 면접 질문 세트 공유
기능을 기획하며 나눈 회의 내용이다.
예를 들면 누군가 공유해놓은 아래와 같은 면접 질문 세트가 있다고 가정해보자
이 면접 질문 세트는 DB에 아래와 같은 형식으로 저장될 것이다.
참고. 예시를 들기 위해 엄청 간소화 한 버전이고
실제는 아래 처럼 구성되어 있다.
[question_sets] --(1:N)--> [questions] --(1:1)--> [answers]
질문 세트 ID | 질문 세트 제목 | 질문 | 답변 | 작성자 |
---|---|---|---|---|
1 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A |
만약 우리 서비스 이용자 B가 해당 질문 세트가 맘에 들어서 북마크를 하고 사용한다고 가정해보자
문제는 질문 세트 작성자 A가 해당 질문 세트를 수정할 때 발생한다.
질문 세트 ID | 질문 세트 제목 | 질문 | 답변 | 작성자 |
---|---|---|---|---|
1 | 면접 질문 세트 | HTTP는 무엇인가요? | HTTP는 HyperText Transfer Protocol의 약자로... | A |
이렇게 되면 이용자 B는 본인이 찜을 했던 시점과 전혀 다른 질문 세트를 북마크하게 된다.
그러면 여기서 판단을 해야한다.
이용자 B는 다음 중 어떤 방식을 원할까?
1. 질문 세트의 수정 사항이 자동으로 반영
원하지 않은 질문이나 변경된 답변까지 적용되어 혼란을 줄 수 있음
2. 질문 세트가 수정되더라도 내가 찜한 시점의 내용이 유지
질문 세트를 복제해서 따로 저장해야 하므로 DB 구조를 고민해야 함
예를 들어, A 사용자가 아래 질문 세트를 북마크하고 연습했다고 가정해보자.
번호 | 질문 |
---|---|
1 | 쿠키와 세션의 차이는? |
2 | JWT는 왜 사용하는가? |
며칠 뒤 A가 다시 복습하려고 열었는데, 질문 세트가 아래처럼 바뀌어 있다.
번호 | 질문 |
---|---|
1 | HTTP와 HTTPS의 차이는? |
2 | JWT와 OAuth의 차이는? |
이 경우 A는 "내가 연습하던 질문이 아니네?", "답변도 달라졌고, 복습이 어렵다..." 라는 혼란을 겪게 된다.
따라서 우리는 사용자가 북마크한 시점의 질문 세트가 그대로 유지되어야 한다고 판단했다.
이 방식이 사용자 경험 측면에서 더 신뢰할 수 있고 예측 가능하기 때문이다.
그러면 북마크 할 때 어떻게 DB에 저장해야 할까?
우선 나이브하게 생각해보자
사용자가 질문 세트를 북마크하는 시점에 해당 질문 세트를 복제해서 관리하는 경우이다.
질문 세트 ID | 질문 세트 제목 | 질문 | 답변 | 작성자 | 구독자 |
---|---|---|---|---|---|
1 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A | |
2 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A | B |
이제, 이용자 B는 작성자 A가 수정하여도 북마크 시점과 같은 질문세트를 볼 수 있게 되었다. 해피 엔딩..?
100만 명이 해당 질문 세트를 북마크하게 되면 어떻게 될까
질문 세트 ID | 질문 세트 제목 | 질문 | 답변 | 작성자 | 구독자 |
---|---|---|---|---|---|
1 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A | |
2 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A | B |
3 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A | C |
4 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A | D |
... | ... | ... | ... | ... | ... |
딱 봐도 불필요한 데이터가 반복되는 게 느껴진다.
그러면 우리는 이 데이터를 어떻게 우아하게 관리할 수 있을까?
면접 질문세트
질문 세트 ID | 버전 | 질문 세트 제목 | 질문 | 답변 | 작성자 |
---|---|---|---|---|---|
1 | 1 | 면접 질문 세트 | 토큰과 세션의 차이는 무엇인가요? | 토큰은 ... 세션은 ... 입니다. | A |
1 | 2 | 면접 질문 세트 | HTTP는 무엇인가요? | HTTP는 HyperText Transfer Protocol의 약자로... | A |
면접 질문 북마크 테이블
구독 ID | 질문 세트 ID | 버전 | 구독자 |
---|---|---|---|
1 | 1 | 1 | B |
2 | 1 | 1 | C |
3 | 1 | 2 | D |
... | ... | ... | ... |
아까와는 확실히 중복된 데이터가 적은 게 느껴진다.
이제 사용자마다 다른 버전 참조도 가능하면서 중복된 데이터를 방지하는 구조를 가지게 됐다.
근데 이 방식대로 라면...
질문 하나라도 바뀌면 새로운 버전의 전체 질문 세트를 생성해야 하는 거 아냐?
그래서 세트 / 질문 둘 다 버전으로 관리하기로 결정했다.
질문 하나가 수정되더라도 다른 질문들이 중복적으로 생성될 필요없게 되었다.
북마크라는 하나의 작은 기능을 기획하면서도 굉장히 고민할 게 많다고 느꼈다.