개발 slecs

결제 테이블 누락으로 생긴 스키마와 라이브 DB 불일치 해소

목차

한 줄 요약: 설계 문서(GAME_DESIGN)에는 있지만 schema.sql에는 빠진 purchase 테이블을 추가해 라이브 DB와의 불일치를 메웠다.

갭이 생기는 이유

이 작업은 단순 테이블 추가처럼 보이지만, 실은 설계와 구현이 어떻게 벌어지는지를 보여주는 사례였다. GAME_DESIGN에 purchase 테이블이 명시되어 있었는데, 정작 schema.sql(우리가 새 환경을 셋업할 때 참조하는 원본 스키마)에는 빠져 있었다.

이런 갭이 발생하는 보통의 시나리오:

  • 초기 마이그레이션: 레거시 DB에서 테이블이 있는데, 새 버전을 위한 스키마 설정 시 누락
  • 후발 개발: 프로덕션 DB에서 직접 테이블을 생성했지만, schema.sql 업데이트를 미루다가 결국 깜빡함
  • 문서 선행 설계: GAME_DESIGN에서 테이블을 정의했지만, 개발팀이 구현할 때 별도로 추가하지 않은 케이스
  • 다중 팀 개발: 다른 팀원이 추가한 테이블이 메인 리포 스키마에 반영되지 않음
상황 위험도 발견 난이도
라이브엔 있는데 schema.sql엔 없음 높음 낮음 (운영 중 문제 발생)
schema.sql엔 있는데 라이브엔 없음 중간 높음 (배포 시점까지 모를 수 있음)
칼럼 정의만 미묘하게 다름 낮음 (작동하지만) 매우 높음 (숨어서 버그 원인이 됨)

왜 이걸 지금 수정했나

purchase 테이블은 결제 플랫폼 도메인에서 핵심 엔티티다. 새로운 팀원이 온보딩될 때, schema.sql을 읽으면 purchase 테이블이 없어 보인다. 그러다가 라이브 쿼리나 마이그레이션 스크립트에서 purchase를 참조하는 코드를 만나면 "어? 이게 어디서 온 거지?"라는 혼란이 생긴다.

또한 DB 복제/복원 작업 시 문제가 될 수 있다:
- schema.sql을 기준으로 새 스테이징 환경을 만들면 purchase가 없음
- 테스트 코드가 purchase 데이터를 기대하면 실패
- 마이그레이션이 손상될 가능성

어떻게 처리했는가

-- GAME_DESIGN에 정의된 purchase 테이블 구조를
-- schema.sql에 정식으로 추가

CREATE TABLE purchase (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,
  game_id BIGINT NOT NULL,
  purchased_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  amount INT NOT NULL,
  -- 다른 칼럼들...
  FOREIGN KEY (user_id) REFERENCES users(id),
  FOREIGN KEY (game_id) REFERENCES games(id)
);

라이브 DB와 schema.sql을 비교해서 누락된 부분을 찾아내고, GAME_DESIGN과도 대조해 정의를 정확하게 가져왔다. 이 테이블은 이미 프로덕션에서 구동 중이었으므로 마이그레이션은 필요 없고, schema 정의만 코드베이스에 기록하는 작업이었다.

배운 것들

1. 설계 문서와 구현 코드의 간극은 자동화로는 줄일 수 없다
누군가 수동으로라도 주기적으로 점검해야 한다. 우리 팀에선 분기별 schema audit을 추가했다.

2. schema.sql의 '원본성'을 지키는 게 중요하다
schema.sql이 프로덕션 DB의 진실의 원천(source of truth)이 되려면, 라이브 변경 후에도 반드시 여기를 업데이트하는 문화가 필요하다.

3. 온보딩 관점에서 설계 문서와 코드는 일치해야 한다
새로운 팀원이 GAME_DESIGN을 읽었는데 schema.sql에서 그 테이블이 없으면, 신뢰도가 떨어진다.

이런 작은 갭들이 모이면 결국 더 큰 리스크가 된다. 이번 수정은 단순 테이블 추가지만, "설계와 현실을 어떻게 맞춰갈 것인가"라는 더 큰 질문을 던져줬다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.