사이즈, 색상, 재고 별 옵션… 복잡할수록 설계가 생명입니다. Laravel + MySQL로 구조부터 확실하게 잡아봅시다.
안녕하세요!
지난 2편에서 상품 등록 기능을 Laravel + Vue.js로 구현해봤는데요, 이번에는 쇼핑몰에서 빼놓을 수 없는 상품 옵션과 카테고리 연동을 다뤄보겠습니다. 옷 쇼핑몰을 예로 들면 ‘사이즈(S/M/L)’나 ‘색상(검정/흰색)’ 같은 옵션을 상품에 붙이고, 메뉴에는 ‘남성 > 상의 > 반팔티’ 같은 카테고리 트리도 보여줘야 하잖아요? 이 기능은 사실 DB 설계가 핵심이고, 잘못 시작하면 유지보수가 지옥 됩니다.
Laravel의 관계형 모델과 Eloquent ORM을 활용해서, 복잡한 옵션 구조도 쉽게 관리할 수 있게 설계해볼게요.
실전에서 바로 쓸 수 있는 설계 팁도 함께 담았습니다!
목차
옵션 & 카테고리 설계 원리 이해하기
상품 옵션은 단순한 텍스트가 아닙니다. 색상(컬러)과 사이즈(S/M/L)의 조합이 각각 재고와 가격을 가지는 경우, “옵션명”과 “옵션값”, 그리고 그것의 “조합 정보”를 따로 관리해야 유지보수가 쉬워져요.
카테고리도 마찬가지예요. 보통은 1단-2단-3단 구조의 계층형 데이터를 쓰는데, Eloquent 관계를 잘 활용하면 하위 분류까지 손쉽게 조회하고 메뉴에 출력할 수 있어요.
MySQL + Laravel Eloquent 모델링
Laravel의 hasMany
, belongsToMany
, hasOneThrough
등을 활용해 복잡한 관계도 간단하게 관리할 수 있습니다.
테이블 | 설명 |
---|---|
products | 상품 정보 |
categories | 카테고리 (parent_id로 계층 구조) |
product_category | 상품 - 카테고리 다대다 관계 (pivot) |
options | 옵션 그룹 (예: 색상, 사이즈) |
option_values | 각 옵션의 선택값 (예: 검정, M) |
product_option_sets | 상품별 옵션 조합 (재고, 가격 포함) |
각 옵션 조합은 별도의 row로 등록되며, 수량, 가격, 노출 여부 등을 별도로 관리할 수 있어야 합니다.
옵션/카테고리 등록 폼 구현 (Vue 기반)
Vue에서는 v-for를 활용해 옵션/카테고리를 반복 출력하고, 사용자가 직접 입력하거나 체크박스로 선택하는 방식으로 구성하면 UX가 좋아집니다.
-
v-model
로 입력값 바인딩 -
watch
로 옵션값 변경 시 조합 재계산 - 카테고리는
tree view
또는select option
으로 계층 처리
다음 STEP에서는 상품과 이 옵션/카테고리를 연동하는 로직과 UI 구성 방식을 다룹니다.
상품과 옵션/카테고리 연동 구조
상품과 옵션, 카테고리를 연결할 땐 다대다 관계를 기반으로 하되, 카테고리는 sync()
를 사용해 자동 연결하고, 옵션 조합은 별도 테이블로 등록해 개별 재고/가격을 입력하는 구조를 추천합니다.
- 상품 등록 시 카테고리 ID 배열 전달 →
$product->categories()->sync([...])
- 선택된 옵션 조합 → JSON 또는 배열로 서버에 전송
- Laravel 컨트롤러에서 반복문으로
ProductOptionSet
레코드 생성 - Vue에서는 옵션값 선택 시 자동 조합 목록 생성
관리자 UI 구성 전략 (옵션 트리, 반복폼)
관리자용 옵션 입력 UI는 트리형 + 동적 반복폼 형태가 직관적입니다. Vue의 v-for
와 v-if
를 활용해 조건부 렌더링을 적용하고, 옵션 조합마다 가격/재고 입력 필드를 보여주면 됩니다.
UI 요소 | 구현 방식 | 비고 |
---|---|---|
옵션값 반복폼 | v-for + v-model | 값 추가/삭제 가능 |
옵션 조합 목록 | watch로 자동 생성 | 조합별 가격/재고 입력 |
카테고리 선택 | Tree select 또는 다중 select | 계층 구조 반영 |
실전에서 자주 막히는 포인트 & 팁
- JSON 옵션 조합을 DB에 저장 시
cast
활용 (Laravel 모델에 array로 캐스팅) - 옵션값 변경 시 조합 리렌더링 처리 – 무한 루프 방지 주의
- DB 트랜잭션으로 상품/옵션/카테고리 한 번에 저장 처리
- 프론트에서 조합 미리보기 기능 추가 시 UX 향상
네. 조합마다 재고/가격이 다르기 때문에 별도 테이블에 관리하는 것이 실무에서 훨씬 유리해요. JSON으로만 처리하면 검색과 업데이트가 불편해집니다.
DB에는 parent_id 구조로 저장하고, Vue나 Blade에선 재귀적으로 트리를 구성합니다. Laravel의 self-referencing relationship을 활용하면 간단해요.
Vue에서 선택된 옵션 배열로 모든 경우의 수를 만들고, 그것을 v-for로 출력하면 됩니다. lodash의 _.flatten
과 _.zip
도 유용해요.
기획에 따라 달라요. 다중 카테고리 허용할 경우 pivot 테이블로 처리하고, 단일 연결만 원한다면 product 테이블에 category_id만 있어도 됩니다.
option_values 테이블에 sort_order 필드를 추가하면 되고, Vue에서는 드래그앤드롭 UI를 통해 순서를 쉽게 조정할 수 있어요.
각 옵션 조합에 수량 필드를 포함하고, 주문이 들어올 때 해당 조합의 재고를 차감하는 방식으로 처리합니다. 트랜잭션 처리가 중요해요.
상품 옵션과 카테고리 구조는 쇼핑몰 설계의 중심축입니다.
이번 포스팅을 통해 “처음부터 구조를 잘 잡는 것이 얼마나 중요한가”를 느끼셨길 바랍니다. 특히 Laravel의 관계형 모델은 MySQL 구조와 찰떡궁합이라, 설계만 잘하면 후속 개발도 매우 수월해요. 실제로 제가 맡았던 프로젝트에서 이 구조를 기준으로 2년 넘게 유지보수하며 기능을 붙였는데도 큰 리팩토링 없이 잘 운영되고 있어요. 처음 설계가 결국 시간을 절약해줍니다.
다음 편에서는 “상품 옵션 기반 재고 및 가격 연동”을 심화 주제로 다뤄볼게요.
질문이나 더 궁금한 내용은 댓글이나 DM으로 주셔도 좋아요.
읽어주셔서 감사합니다 🙏
'💻 쇼핑몰 자동화 & 웹 개발 가이드' 카테고리의 다른 글
[쇼핑몰 개발] Laravel 옵션 캐싱 + 속도 최적화 핵심 전략 (2) | 2025.05.23 |
---|---|
[쇼핑몰 개발] 상품 옵션 기반 재고 및 가격 관리 시스템 구축 (2) | 2025.05.22 |
[쇼핑몰 개발] Vue + Laravel 상품 등록 시스템 만들기 실습 (3) | 2025.05.20 |
[쇼핑몰 개발] PHP + MySQL로 구축하는 실전 쇼핑몰 설계 전략 (4) | 2025.05.19 |
[쇼핑몰 개발] 실전 시리즈 시작! Laravel + Vue + MySQL 기반 개발 안내 (2) | 2025.05.16 |