상품 수가 많은 쇼핑몰의 DB 설계
DB 작성 · 수정 · 글쓴이 미션비
핵심 답변
상품 수가 많은 쇼핑몰은 '품목(보여 주는 상품)'과 '규격(실제로 파는 단위)'을 나누고, 판매 단위와 가격 계산식을 한 곳에서만 정의하는 것이 출발점입니다. 대량 등록은 임시 테이블에서 검증한 뒤 반영하고, 가격 비교 피드처럼 무거운 출력은 미리 만들어 둔 스냅샷을 읽게 합니다. 모든 테이블의 문자셋·정렬 규칙을 통일해 두지 않으면 나중에 조인 자체가 실패합니다.
상품이 많아지면 무엇이 달라지나
상품이 수백 개일 때는 어떤 구조로 만들어도 운영이 됩니다. 수만 개 규격을 다루기 시작하면 이야기가 달라집니다. 한 번의 잘못된 계산식이 수천 개 상품에 동시에 퍼지고, 목록 화면의 정렬 하나가 서버를 느리게 만들고, 같은 정보를 여러 곳에 복사해 둔 것이 조금씩 어긋나기 시작합니다.
아래는 미션비가 공구·산업용품 쇼핑몰 툴ON을 직접 운영하며 정리한 기준입니다. 규격이 많은 B2B 상품을 전제로 하지만, 상품 수가 많은 쇼핑몰 대부분에 그대로 적용됩니다.
1. 품목과 규격을 나눈다
| 품목 | 고객이 보는 상품 한 건. 상품명, 설명, 이미지, 카테고리, 제조사 |
|---|---|
| 규격 | 실제로 파는 단위. 규격명, 판매 단위 수량, 판매가·할인가, 재고, 판매 상태 |
| 주문 항목 | 품목이 아니라 규격을 참조 |
주문·재고·외부 피드·통계가 모두 규격을 기준으로 이어지면, 같은 상품의 규격별 판매량이나 가격 변경 이력을 따로 계산하지 않아도 됩니다.
2. 가격 계산식은 한 곳에서만
판매가와 할인가가 함께 있으면 "실제로 결제되는 단가"를 구하는 식이 생깁니다. 이 식이 주문 화면, 장바구니, 외부 가격 비교 피드에 각각 따로 구현되면 언젠가 하나만 바뀝니다.
특히 묶음으로만 파는 규격이 위험합니다. 묶음 가격을 판매 단위 수량으로 나눠 "낱개 단가"로 보여 주고 싶은 유혹이 생기는데, 그 가격으로는 실제로 살 수 없습니다. 가격 비교 채널에서는 피드 가격과 실제 결제 금액이 다르면 노출 제외 같은 제재 대상이 됩니다. 툴ON은 주문 단가·구글 쇼핑 피드·네이버 쇼핑 피드가 모두 같은 계산식을 쓰도록 맞추고, 판매 단위는 가격을 나누는 대신 상품명과 안내 문구로 표시합니다.
3. 같은 정보를 문자열로 복사하지 않는다
제조사·브랜드명을 상품마다 문자열로 저장해 두면, 같은 브랜드가 "OO", "OO(주)", 공백이 섞인 표기로 갈라집니다. 제조사는 별도 테이블로 두고 상품은 식별자로 참조하는 것이 원칙입니다. 이미 문자열로 쌓여 있다면, 출력할 때 쓸 표기를 "정식 표기 → 보조 표기 → 빈 값" 순서의 규칙으로 정하고 그 규칙을 모든 화면과 피드에서 같이 씁니다.
4. 대량 등록은 임시 테이블을 거친다
- 엑셀·외부 데이터를 임시 테이블에 그대로 적재합니다.
- 필수값, 중복 코드, 존재하지 않는 카테고리·제조사, 가격 이상치를 검사합니다.
- 검사 결과를 운영자에게 보여 주고, 통과한 행만 본 테이블에 반영합니다.
- 같은 파일을 다시 올려도 중복되지 않도록 행 단위 키로 갱신(UPSERT)합니다.
본 테이블에 바로 넣으면 한 줄의 오류가 수천 개 상품의 판매 상태를 바꿔 놓을 수 있습니다.
5. 무거운 출력은 미리 만든다
가격 비교 사이트용 전체 상품 피드처럼 수만 행을 한 번에 만드는 출력은, 요청이 올 때마다 조인해서 만들면 쇼핑몰 응답까지 느려집니다. 툴ON은 관리자 애플리케이션의 배치가 피드 한 줄 한 줄을 미리 렌더링해 스냅샷 테이블에 저장하고, 쇼핑몰은 그 스냅샷을 읽어 내보내기만 합니다. 최근 판매 수량처럼 정렬에 쓰는 값도 배치로 계산해 규격 행에 저장해 둡니다.
6. 문자셋과 정렬 규칙을 통일한다
테이블마다 문자셋이나 정렬 규칙(collation)이 다르면, 평소에는 문제가 없다가 두 테이블을 조인하는 순간 "Illegal mix of collations" 오류로 쿼리가 실패합니다. 새 테이블을 만들 때 정렬 규칙을 생략하면 DB 기본값이 아니라 서버 기본값이 붙는 경우도 있습니다.
- 모든 신규 테이블 DDL에 문자셋과 정렬 규칙을 명시합니다.
- information_schema 를 조회하는 점검 쿼리로 표준에서 벗어난 컬럼을 주기적으로 찾습니다.
- utf8(utf8mb3) 테이블을 utf8mb4 로 바꾸는 것은 재인코딩과 테이블 재구축이 필요한 작업이므로 따로 계획합니다.
주의사항
- 가격·판매 상태를 일괄로 바꾸는 기능에는 변경 전 값을 이력으로 남깁니다. 되돌릴 수 없으면 일괄 기능을 쓰기 어렵습니다.
- 카테고리 구조를 바꿀 때는 기존 카테고리의 이력을 남겨 과거 통계와 외부 피드 매핑이 끊기지 않게 합니다.
- 설계 문서와 구현은 시간이 지나면 어긋나기 쉽습니다. 가격·단위 같은 핵심 규칙은 문서와 코드를 함께 점검합니다.
정리
상품 수가 많은 쇼핑몰의 DB는 품목과 규격의 분리, 한 곳에만 있는 가격 규칙, 복사하지 않는 기준 정보, 검증을 거치는 대량 등록, 미리 만든 무거운 출력, 통일된 문자셋으로 버팁니다. 화려한 기술보다 "같은 값을 두 군데서 계산하지 않는다"는 원칙이 가장 많은 사고를 막습니다.