블로그 본문
[비즈니스 분석] 마이페이지(myPage.js)의 4중 복합 조인 주문 조회 쿼리 최적화 및 고객 리뷰 등록/수정/삭제 라이프사이클 구현
니꼴라 클라우드 테크 9월 21, 2026📌 목차 바로가기
결제가 성공적으로 마무리되고 데이터가 주문 테이블로 이관되었으니, 이제 사용자가 자신의 과거 구매 이력을 조회하고, 구매한 의류 상품에 대해 평점과 실구매 후기를 남기거나 관리하는 마이페이지(myPage.js) 구현으로 나아갈 차례입니다. 이번 포스팅에서는 RDBMS의 대미를 장식하는 4중 복합 조인(4-Way JOIN) 쿼리 최적화와, 주문 날짜별 데이터 그룹화, 그리고 고객 리뷰(Prod_evals)의 등록, 조회, 수정, 삭제(CRUD) 라이프사이클 설계를 설명하겠습니다.
1. RDBMS의 꽃: Orders-Ord_items-Products-Prod_evals 4중 복합 조인(JOIN) 쿼리 구조 분석
마이페이지 화면은 단일 테이블 조회만으로는 결코 완성할 수 없는, RDBMS 조인(JOIN) 연산의 모든 노하우가 결집된 종합 비즈니스 레이어입니다.
고객 한 명이 마이페이지에 접속했을 때 보여주어야 할 정보는 다음과 같이 4개 테이블에 흩어져 있습니다:
Orders(주문 마스터): 주문 번호(ord_no), 주문 일자(ord_date), 총 결제 금액(ord_amount), 주문 고객 ID(cust_id).Ord_items(주문 상세): 해당 주문에 포함된 상품 코드(prod_cd), 선택 사이즈(prod_size), 구매 수량(ord_qty).Products(상품 마스터): 상품명(prod_name), 단가(price), S3 이미지 URL(prod_img).Prod_evals(상품평): 해당 고객이 해당 상품에 대해 작성한 기존 평점(eval_score) 및 한줄평(eval_comment), 평가 작성일(eval_date).
■ 4중 LEFT JOIN 쿼리 설계 및 최적화
이 4개 테이블을 단 한 번의 효율적인 데이터베이스 네트워크 왕복(Single Round-Trip)으로 스캔해 오기 위해 다음과 같은 4중 LEFT JOIN 복합 쿼리를 가동합니다:
SELECT
O.ord_no, O.ord_date, O.ord_amount,
I.cart_seq_no, I.prod_cd, I.prod_size, I.ord_qty,
P.prod_name, P.price, P.prod_img,
E.eval_seq_no, E.eval_score, E.eval_comment, E.eval_date
FROM Orders O
INNER JOIN Ord_items I ON O.ord_no = I.ord_no
INNER JOIN Products P ON I.prod_cd = P.prod_cd
LEFT JOIN Prod_evals E ON I.prod_cd = E.prod_cd AND O.cust_id = E.cust_id
WHERE O.cust_id = ?
ORDER BY O.ord_no DESC, I.cart_seq_no ASC
INNER JOIN적용 구문:Orders와Ord_items,Products간에는 반드시 일치하는 주문 상품 정보가 존재하므로INNER JOIN을 적용해 데이터 결속을 보장합니다.LEFT JOIN적용 구문:Prod_evals와의 결합 시LEFT JOIN을 대입합니다. 이는 고객이 구매 후 아직 리뷰를 작성하지 않은 상품이더라도 주문 이력 목록에서 소멸하지 않고 정상 노출되게 만들면서, 이미 작성한 리뷰가 있다면 해당 리뷰 데이터(eval_score,eval_comment)를 유기적으로 가져오도록 보장하는 방어적 쿼리 설계 수칙입니다.- 조인 조건의 이중 바인딩 (
E.prod_cd = I.prod_cd AND E.cust_id = O.cust_id): 특정 고객이 본인이 구매한 특정 상품에 남긴 리뷰만을 일대일로 정확히 맵핑하기 위해 상품 코드와 고객 아이디를 조인 조건으로 함께 바인딩합니다.
2. 마이페이지 비즈니스 로직: 주문 이력 그룹화 및 고객 리뷰(Prod_evals) CRUD 라이프사이클
4중 조인 쿼리로 수득한 평탄화된(Flattened) 레코드셋을 프론트엔드 카드 구조로 정돈하고, 리뷰 데이터를 관리하는 비즈니스 로직을 구축합니다.
① 주문 번호(ord_no) 기준 데이터 그룹화 (Data Grouping)
쿼리 결과는 1개의 주문에 3개의 상품이 포함되어 있다면 3개의 행(Row)으로 반환됩니다. 백엔드 가공 단계에서 자바스크립트 reduce() 연산을 적용해 ord_no를 키(Key)로 하는 그룹화 객체를 생성하여, 하나의 주문 카드 내에 여러 구매 상품 항목들이 깔끔하게 중첩 배열 형태로 나열되도록 SSR HTML 템플릿을 조립합니다.
② 고객 리뷰(Prod_evals) CRUD 라이프사이클
구매 확정된 상품에 대해 고객이 자율적으로 후기를 관리할 수 있도록 완전한 CRUD 엔드포인트를 수립합니다.
- 리뷰 등록 (
POST /mypage/review):- 자격 검증: 해당 사용자가 실제 해당 상품을 결제 구매했는지(
Orders및Ord_items이력) 검증합니다. - 중복 작성 차단: 동일 주문/상품에 대해 이미 작성된 리뷰가 있는지 확인 후
INSERT INTO Prod_evals (cust_id, prod_cd, eval_score, eval_comment, eval_date) VALUES (?, ?, ?, ?, CURDATE())연산을 집행합니다.
- 자격 검증: 해당 사용자가 실제 해당 상품을 결제 구매했는지(
- 리뷰 조회 (
GET /mypage):- 마이페이지 주문 이력 카드 내에 작성된 별점(
★)과 한줄평 텍스트를 노출하고, 리뷰가 없는 상품에는 [리뷰 작성] 버튼을, 기존 리뷰가 있는 상품에는 [리뷰 수정] 및 [리뷰 삭제] 버튼을 동적 전환 렌더링합니다.
- 마이페이지 주문 이력 카드 내에 작성된 별점(
- 리뷰 수정 (
PUT /mypage/review/:id):- 소유권 검증:
WHERE eval_seq_no = ? AND cust_id = ?조건절을 통해 타인의 리뷰를 무단 수정하려는 인가 우회 공격을 차단한 뒤 평점 및 한줄평을UPDATE처리합니다.
- 소유권 검증:
- 리뷰 삭제 (
DELETE /mypage/review/:id):- 본인 소유권 검증 후
DELETE FROM Prod_evals WHERE eval_seq_no = ? AND cust_id = ?연산을 집행하여 리뷰를 완전히 제거합니다.
- 본인 소유권 검증 후
3. 4중 복합 조인 및 마이페이지 리뷰 CRUD 라이프사이클 아키텍처 다이어그램
AWS RDS MySQL의 Orders, Ord_items, Products, Prod_evals 4개 테이블을 4중 LEFT JOIN으로 엮어 주문 이력을 그룹화하고, myPage.js 라우터가 세션 소유권(cust_id) 검증 하에 고객 리뷰 CRUD(등록/수정/삭제) 라이프사이클을 가동하는 마이페이지 수송 아키텍처 다이어그램입니다.
마치며: [둘째마당] SQL 기반 쇼핑몰 구축 대단원의 막을 내립니다!
오늘 우리는 백엔드 비즈니스 시스템 완성의 정점이라 할 수 있는 4중 복합 조인(Orders-Ord_items-Products-Prod_evals) 쿼리 최적화와 주문 날짜별 데이터 그룹화, 그리고 고객 리뷰의 등록, 조회, 수정, 삭제(CRUD) 라이프사이클을 구축했습니다.
"RDBMS의 엄격한 참조 정합성과 물리 스키마 설계, Amazon S3 미디어 분산 연동, MVC 아키텍처, 세션 안보 모듈, 복합 조인 및 ACID 결제 트랜잭션까지, 엔터프라이즈 레벨의 정형 데이터 웹 서비스 전체 라이프사이클을 우리 손으로 완벽하게 수립해 낸 것입니다."
정형 데이터베이스와 SQL 아키텍처를 완벽하게 정복했으니, 이제 시선을 넓혀 비정형/반정형 대용량 빅데이터 처리와 유연한 스키마 확장을 보장하는 NoSQL 패러다임으로의 대전환을 시작할 시간입니다!
다음 포스팅 [NoSQL 패러다임 전환] 관계형 RDBMS의 한계와 유연한 DocumentDB/MongoDB 문서 지향 데이터베이스의 필요성 편에서는, 고정된 테이블 스키마와 조인 연산의 한계, 빅데이터 트래픽에서의 수평적 스케일아웃(Scale-Out) 제약, 그리고 문서 지향(Document-Oriented) JSON/BSON 데이터 구조가 제공하는 무한한 유연성과 확장성 원리를 설명하겠습니다.
오늘 4중 조인 쿼리 연산 실행 중 에러가 발생했거나, 리뷰 CRUD 엔드포인트 설계에 대한 문의가 있으시다면 주저하지 마시고 운영자 메일로 질의해 주세요. 오늘도 안전하고 똑똑한 클라우딩 라이프 하세요. 감사합니다! 😉
출처
- 이현호. 실무 프로젝트로 완성하는 클라우드 환경에서 DB 구축과 웹 개발. 길벗캠퍼스. 2026.04. (9.2장 '마이페이지 및 리뷰 관리 모듈', 244-255페이지 참조)
- 이현호. "09장. 애플리케이션 개발 - 장바구니_마이페이지_설명오디오.m4a" 설명 오디오 가이드 스크립트 기반 Orders-Ord_items-Products-Prod_evals 4중 복합 조인 필요성, LEFT JOIN을 통한 리뷰 미작성 상품 노출 보장, ord_no 데이터 그룹화 및 고객 리뷰 CRUD 라이프사이클 인가 보안 비하인드 대화록 완벽 반영.
- MySQL 8.0 Reference Manual - Multiple Joins Optimization (https://dev.mysql.com/doc/refman/8.0/en/join.html) 및 MDN Express Routing Guide.
자주 묻는 질문 (FAQ)
Q. 마이페이지 구축 시 Orders, Ord_items, Products 테이블 외에 Prod_evals 테이블을 INNER JOIN이 아닌 LEFT JOIN으로 결합하는 이유는 무엇인가요?
A. 작성된 리뷰가 없는 주문 항목의 누락을 방어하기 위해서입니다. INNER JOIN 사용 시 사용자가 리뷰를 남기지 않은 상품은 교집합이 없어 주문 내역 전체에서 소멸하므로, LEFT JOIN을 적용하여 리뷰 작성 여부와 무관하게 모든 구매 이력을 완벽하게 노출해야 합니다.
Q. 4중 조인 쿼리 결과 반환 시 하나의 주문에 여러 상품이 포함되어 중복 수신되는 레코드 데이터를 프론트엔드에 그룹화하여 표현하는 방법은 무엇인가요?
A. 백엔드 가공 단계에서의 주문 번호(ord_no) 기준 객체 그룹화입니다. 쿼리 수득 배열을 reduce() 또는 forEach()로 순회하며 ord_no를 키(Key)로 하는 맵 객체로 재구성함으로써, 하나의 주문 번호 아래 여러 상품 아이템 배열을 중첩 구조로 깔끔하게 조립해 SSR HTML로 렌더링합니다.
Q. 마이페이지 내에서 고객 리뷰 수정(PUT) 및 삭제(DELETE) 처리 시 보안성을 보장하기 위한 핵심 검증 기법은 무엇인가요?
A. SQL WHERE 절에서의 세션 소유권(cust_id) 이중 검증 바인딩입니다. URL 파라미터의 eval_seq_no만으로 대상을 지정할 경우 타인 리뷰 무단 수정/삭제 공격에 노출되므로, 반드시 'WHERE eval_seq_no = ? AND cust_id = ?' 구문을 대입하여 본인이 작성한 리뷰만 제어 가능하도록 수호해야 합니다.
