학습 포털 메인 화면에 추천 과정 영역이 다섯 개 있었고 각각 다른 기준으로 목록을 만들고 있었다. recommend_new 부터 recommend_popular 까지 테이블이 종류마다 따로 있어서 이것을 하나로 합치는 것이 나은지를 검토하게 됐다.
Table of contents
Open Table of contents
상황 — 다섯 개의 추천 영역
합치자는 생각이 나온 이유는 구조가 비슷해 보였기 때문이었다. 다섯 테이블의 컬럼이 대체로 겹치니 종류를 나타내는 type 컬럼 하나를 두면 될 것 같았다. 합치는 것과 나누는 것 두 가지 길이 있었다.
그런데 구조가 비슷하다는 것이 합칠 이유가 되는지는 따로 물어야 했다. 합치면 얻는 것이 무엇인지가 그 판단의 기준이다.
판단 기준 — 나눌지 합칠지의 기준
합쳐서 얻는 대표적인 이득은 한 번의 조회로 여러 종류를 함께 가져오는 것이다. 그래서 이 다섯 개를 실제로 함께 조회하는지를 봤다.
화면에서는 영역별로 따로 그리고 있었고 한 번에 가져오는 자리가 없었다. 합쳐도 그 이득을 쓸 데가 없다는 뜻이었다.
함께 조회하지 않으면 나눈다
함께 조회하지 않으면 합쳐서 얻는 것이 거의 없고 조회마다 WHERE type = ? 조건이 하나씩 더 붙는 것만 남는다. 그래서 나눠 두는 쪽이 낫다는 결론이 나왔다.
종류가 여럿이라는 사실 자체는 합칠 근거도 나눌 근거도 아니었다. 판단은 그것을 어떻게 조회하는지가 정한다.
검증 — 쓰기 패턴과 참조 대상
읽는 쪽만이 아니라 쓰는 쪽도 봤는데 각 종류를 cron 배치가 TRUNCATE 로 통째로 지우고 다시 채우는 구조였다. 합쳐 두면 한 종류를 갈아엎는 동안 다른 종류의 조회가 영향을 받는다.
종류마다 참조하는 대상이 course 와 instructor 로 다르다는 것도 있었다. 합치면 그 참조를 FOREIGN KEY 제약으로 걸 수 없게 되므로 자료가 어긋나도 DB가 안 막아 준다.
설정 — 다국어 분리와 번호의 연속성
여기에 다국어 항목은 recommend_i18n 별도 테이블로 빼는 것으로 정했는데 언어가 하나 늘 때 스키마를 안 고쳐도 되기 때문이다. 대신 조회할 때 WHERE lang = ? 조건을 빠뜨리면 행이 배로 늘어나므로 그 점을 주의 사항으로 적었다.
인계받은 정의서를 보다가 테이블 번호에 빈 자리가 있는 것도 확인했다. 번호가 끊긴 자리는 문서에 없는 테이블이 있다는 신호라서 그것부터 확인하는 것이 순서였다.
정리
- 테이블을 나눌지 합칠지는 조회 패턴이 정한다
- 종류가 여럿이라는 사실 자체는 근거가 아니다
- 함께 조회하지 않으면 나눈다
- 합쳐서 얻는 이득을 쓸 데가 없기 때문이다
- 쓰기 패턴도 본다
- 배치가 통째로 갈아엎는 구조면 나눠야 서로 안 막는다
- 참조 대상이 다르면 합칠 때 제약을 포기하게 된다
- 다국어를 별도 테이블로 빼면 언어 추가에 스키마 변경이 없다