블로그 본문

[DB 물리 설계] MySQL Workbench를 활용한 쇼핑몰 핵심 6개 테이블 구축 및 제약조건 수립 실습

📌 목차 바로가기

    이번 포스팅에서는 의류 쇼핑몰 비즈니스를 영위하는 데 필요한 고객 관리, 상품 관리, 주문 처리의 3대 축을 지탱하는 6대 핵심 테이블을 물리 모델링하고 실제 SQL 스크립트로 구축하는 과정을 단계별로 다루겠습니다.

    이 과정에서 비밀번호 보관 설계 법칙, 상품 사이즈 무결성을 수호하는 CHECK 제약조건, 그리고 16MB 대용량 마크업을 수용하는 MEDIUMTEXT 데이터 타입의 선정 사상까지 명확하게 가르쳐 드리겠습니다.

    1. 비즈니스 정책의 코드화: ERD 논리 설계와 데이터 무결성

    데이터베이스 모델링에서 ERD(Entity Relationship Diagram)를 설계하는 것은 단순히 데이터를 저장할 엑셀 표를 나누어 그리는 행위가 아닙니다. 그것은 "우리 회사는 비즈니스를 이렇게 통제하고 가동할 것이다"라는 기업의 경영 및 정보 보호 정책을 컴퓨터가 이해할 수 있는 절대 규칙으로 선언하는 과정입니다.

    우리가 설계한 의류 쇼핑몰 ERD의 논리 모델은 크게 세 가지 비즈니스 축으로 나뉩니다.

    • 고객 관리 축: 고객은 가입 시 아이디(이메일 형식), 비밀번호, 고객명, 휴대폰 번호를 필수로 기입해야 하며, 개별 서비스 이용 약관, 개인정보 수집 가이드라인, 마케팅 수신동의 정보를 선택적으로 제어하여 동의 여부(Y/N)를 명확히 적재해야 합니다.
    • 상품 관리 축: 등록되는 상품은 고유한 상품코드, 상품명, 판매 단가, 상품 유형(상의, 하의 등), 소재 정보를 지녀야 하며 상세 마케팅 소개 정보를 보관해야 합니다.
    • 주문 처리 축 (고객과 상품의 교차점): 고객은 장바구니에 상품과 사이즈를 지정해 담아 보관할 수 있으며, 결제 시 정식 주문 테이블(Orders)과 세부 주문 품목 테이블(Ord_items)로 데이터 상태가 전이되며 데이터 라이프사이클이 흘러가게 됩니다.

    이러한 정책을 완벽하게 수호하기 위해 물리 스키마 설계 단계에서 적용되는 RDBMS의 3가지 핵심 방어 메커니즘을 파헤쳐 보겠습니다.

    2. 물리 설계 단계의 RDBMS 3대 방어 메커니즘

    ① 비밀번호 컬럼 크기의 비밀: VARCHAR(255)의 사상

    회원의 기본 정보를 저장하는 Customers 테이블의 비밀번호 컬럼(passwd) 크기는 무려 VARCHAR(255)로 매우 넉넉하게 잡혀 있습니다. 일반적인 비밀번호 입력값이 10~20자 내외인 것에 비하면 상당한 공간 할당입니다. 이유는 앞으로 7장에서 적용할 bcrypt 단방향 암호화 해시 알고리즘 때문입니다. 사용자가 입력한 평문 비밀번호는 보안상 데이터베이스 디스크에 날것으로 적재되면 안 됩니다. 암호학적 솔트(Salt)가 추가되어 일방향 해싱을 거친 변환값은 입력값의 길이와 상관없이 항상 60자 이상의 복잡한 문자열로 팽창되어 반환됩니다. 따라서 향후 패키지 암호화 기능 도입에 따른 암호문 유실을 원천 예방하기 위해, 최초 설계 시점부터 비밀번호 공간을 VARCHAR(255)로 정밀 할당하는 것이 실무 표준 아키텍처입니다.

    ② 데이터 오염 방지망: CHECK (prod_size IN (...)) 제약조건

    사용자가 장바구니(Carts)에 옷을 담을 때 사이즈 데이터는 임의의 문자열이 될 수 없습니다. 만약 악의적인 클라이언트나 잘못된 API 패킷이 침투하여 사이즈 란에 '슈퍼맨' 같은 유령 텍스트를 전송하면 시스템의 일관성이 붕괴됩니다. RDBMS는 데이터베이스 내부 엔진 레벨에서 데이터를 최종 검문하는 CHECK 제약조건을 가동합니다. CHECK (prod_size IN ('S','M','L','XL','XXL')) 규칙을 수립해 두면, 허용되지 않은 엉뚱한 문자열이 진입하는 즉시 데이터베이스 커널이 데이터 쓰기 동작을 차단(Reject)하고 에러를 발생시켜 오염된 데이터의 입주를 원천 격리 방어합니다.

    ③ 16MB 대용량 마크업 수용: MEDIUMTEXT의 장비

    상품(Products) 테이블의 상품소개(prod_intro) 컬럼은 일반적인 VARCHAR 문자열 대신 MEDIUMTEXT 타입을 채택하고 있습니다. 쇼핑몰의 상품 상세 페이지를 조회해 보면 단순히 텍스트 한 줄만 표시되는 것이 아니라, 길게 배치된 이미지 레이아웃과 화려한 폰트, CSS 스타일 등이 유기적으로 설계된 HTML 웹페이지가 렌더링 됩니다. 이 방대한 양의 디자인 코드(HTML Markup)를 소스 코드 파일이 아닌 데이터베이스 내부에 동적으로 완전히 담아내어 렌더링하기 위해, 최대 16MB 크기의 텍스트 데이터를 통째로 수용할 수 있는 고성능 가상 대용량 텍스트 타입인 MEDIUMTEXT를 장착하여 시스템 유연성을 수립하는 것입니다.

    3. [SQL 스크립트] 쇼핑몰 RDBMS 물리 스키마 DDL

    이전 포스팅의 예제 논리 ERD에 대한 물리 ERD는 다음과 같습니다.

    의류 쇼핑 DB의 물리 모델 ERD

    물리 모델 스키마 명세에 맞추어, shopping_db 데이터베이스에 6개의 상호 의존적 테이블을 구축하는 DDL(Data Definition Language) 명세서입니다.

    -- 1. 사용할 데이터베이스 오픈
    USE shopping_db;
    
    -- 2. Customers(고객) 테이블 생성
    CREATE TABLE Customers (
        cust_id VARCHAR(50) PRIMARY KEY,            -- 고객 ID (이메일 주소 형식)
        passwd VARCHAR(255) NOT NULL,               -- 단방향 암호화 비밀번호 적재용
        cust_name VARCHAR(50) NOT NULL,             -- 고객 실명
        m_phone VARCHAR(11) NOT NULL,               -- 휴대폰 번호 (하이픈 제외 11자리)
        a_term VARCHAR(1) NOT NULL,                 -- 이용약관 동의 여부 (Y/N)
        a_privacy VARCHAR(1) NOT NULL,              -- 개인정보 활용 동의 여부 (Y/N)
        a_marketing VARCHAR(1) NOT NULL             -- 마케팅 정보 수신 동의 여부 (Y/N)
    );
    
    -- 3. Products(의류상품) 테이블 생성
    CREATE TABLE Products (
        prod_cd VARCHAR(5) PRIMARY KEY,             -- 상품 고유 코드
        prod_name VARCHAR(100) NOT NULL,            -- 상품명
        price INT NOT NULL,                         -- 상품 단가
        prod_type VARCHAR(50),                      -- 상품 카테고리 유형 (상의/하의 등)
        material VARCHAR(50),                       -- 상품 소재 정보
        prod_img VARCHAR(100),                      -- S3 또는 로컬 저장소 이미지 경로 URL
        prod_intro MEDIUMTEXT                       -- HTML 태그를 포함하는 대용량 상품 상세 소개문
    );
    
    -- 4. Carts(장바구니) 테이블 생성
    CREATE TABLE Carts (
        cart_seq_no INT AUTO_INCREMENT PRIMARY KEY, -- 장바구니 일련번호 (자동 증가 식별자)
        cust_id VARCHAR(50) NOT NULL,                  -- 외래키: 고객 ID
        prod_cd VARCHAR(5) NOT NULL,                   -- 외래키: 상품 고유 코드
        prod_size VARCHAR(3) NOT NULL CHECK (prod_size IN ('S','M','L','XL','XXL')), -- 사이즈 체크 제약조건
        ord_qty INT NOT NULL,                          -- 담은 수량
        ord_yn VARCHAR(1) NOT NULL,                    -- 주문 전환 완료 여부 (Y: 결제 완료, N: 대기 상태)
        FOREIGN KEY (cust_id) REFERENCES Customers(cust_id),
        FOREIGN KEY (prod_cd) REFERENCES Products(prod_cd)
    );
    
    -- 5. Orders(주문) 테이블 생성
    CREATE TABLE Orders (
        ord_no INT AUTO_INCREMENT PRIMARY KEY,      -- 정식 결제 주문 번호 (자동 증가 식별자)
        ord_date DATE NOT NULL,                     -- 결제 완료 일자 (KST 기준)
        ord_amount INT NOT NULL,                    -- 총 결제 세액 합산 금액
        cust_id VARCHAR(50) NOT NULL,               -- 외래키: 주문자 ID
        FOREIGN KEY (cust_id) REFERENCES Customers(cust_id)
    );
    
    -- 6. Ord_items(주문상세내역) 테이블 생성
    CREATE TABLE Ord_items (
        ord_item_no INT AUTO_INCREMENT PRIMARY KEY, -- 주문상세 고유 일련번호
        ord_no INT NOT NULL,                        -- 외래키: 정식 주문 번호
        cart_seq_no INT,                             -- 외래키: 근원이 된 장바구니 일련번호
        prod_cd VARCHAR(5) NOT NULL,                -- 외래키: 상품 고유 코드
        prod_size VARCHAR(3) NOT NULL,              -- 결제 시점의 선택 사이즈
        ord_qty INT NOT NULL,                       -- 결제 주문 수량
        FOREIGN KEY (ord_no) REFERENCES Orders(ord_no),
        FOREIGN KEY (cart_seq_no) REFERENCES Carts(cart_seq_no),
        FOREIGN KEY (prod_cd) REFERENCES Products(prod_cd)
    );
    
    -- 7. Prod_evals(상품평/고객리뷰) 테이블 생성
    CREATE TABLE Prod_evals (
        eval_seq_no INT AUTO_INCREMENT PRIMARY KEY,  -- 상품평 고유 번호
        eval_score INT NOT NULL,                     -- 부여 평점 점수 (1 ~ 5점 표준 정수)
        eval_comment VARCHAR(1000),                  -- 최대 1000자 제한 한줄평 리뷰 본문
        eval_date DATE NOT NULL,                     -- 상품평 등록 일자
        cust_id VARCHAR(50) NOT NULL,                -- 외래키: 작성 고객 ID
        prod_cd VARCHAR(5) NOT NULL,                 -- 외래키: 평가 상품 고유 코드
        ord_item_no INT NOT NULL,                    -- 외래키: 실구매 영수증 주문 상세 번호 (어뷰징 차단용)
        FOREIGN KEY (cust_id) REFERENCES Customers(cust_id),
        FOREIGN KEY (prod_cd) REFERENCES Products(prod_cd),
        FOREIGN KEY (ord_item_no) REFERENCES Ord_items(ord_item_no)
    );
    

    4. [실습] MySQL Workbench를 통한 DDL 컴파일 및 실행 절차

    이제 로컬 PC에 기동 중인 MySQL Workbench 제어판을 활용하여 클라우드 RDBMS 본진에 테이블을 이식하겠습니다.

    1. Workbench 기동: MySQL Workbench를 실행하고, 등록되어 있는 AWS RDS MySQL 커넥션 카드(admin 계정, default schema: shopping_db)를 더블클릭하여 원격 데이터 소켓 세션을 연결합니다.
    2. 쿼리 창 활성화: 상단 툴바 메뉴에서 New Query Tab 아이콘을 클릭하여 새 도화지를 기상시킵니다.
    3. DDL 붙여넣기 및 전체 드래그: 위의 6개 테이블 생성 DDL 스크립트를 깔끔히 복사하여 쿼리 편집창에 입력합니다.
    4. 컴파일 실행: 쿼리 창 좌측 상단에 위치한 실행(Execute, 번개 모양) 버튼을 누릅니다.
    5. 콘솔 로그 검증: 대화상자 하단 Action Output 탭에 녹색 체크 사인이 순차적으로 6줄 연속 마크되며 Create Table ... 0 row(s) affected라는 메시지가 깔끔히 표시되면 원격 AWS RDS 상에 정밀한 물리 데이터 저장 수송 공간 생성이 완료된 것입니다.
    6. 스키마 새로고침: 좌측 Navigator 패널의 Schemas 영역에서 shopping_db 하위의 Tables 폴더를 마우스 우클릭 후 [Refresh All]을 누르면, 정상 입주한 Customers부터 Prod_evals까지 6개의 가상 테이블 개체들이 줄지어 등장하게 됩니다.

    마치며: 비즈니스를 견디는 RDBMS 인프라 완성

    오늘 우리는 데이터를 설계하는 최고의 시스템 아키텍트로서, 단순 정보 보존을 넘어서 비즈니스 보안 정책과 데이터 오염 방지선, 그리고 암호학적 확장성까지 정교하게 조율된 의류 쇼핑몰 RDBMS 핵심 6대 테이블 물리 빌딩 대단원을 무결하게 마쳤습니다!

    "RDBMS의 물리 설계를 완수한 것은, 가상 도시(AWS VPC) 중앙 광장에 6개의 고성능 자동 검문 게이트를 장착한 특수 물류 창고들을 개설하고, 고객 식별 정보와 핵심 마스터 상품 정보 컨테이너 트럭들을 안전하게 입고시켜 놓은 보안 통제망 구축 프로세스와 일맥상통합니다."

    RDBMS 데이터 본진의 세팅을 완벽하게 마감했으나, 아직 한 가지 중대한 인프라 성능적 의문이 하나 우리 발걸음을 붙잡습니다. 바로 "Products 테이블의 상품 이미지(prod_img 컬럼)들을 데이터베이스 내부에 BLOB 파일 형식으로 직접 우겨넣어 관리할 것인가? 아니면 클라우드 전용 분산 스토리지를 빌릴 것인가?"에 대한 시스템 튜닝 공학적 선택입니다.

    다음 포스팅에서는 클라우드 미디어 자원 관리 및 아키텍처 성능 튜닝의 큰 전환점이 될 [클라우드 미디어 최적화] RDBMS 이미지 직접 저장(Blob)의 한계와 S3 스토리지 연동의 기회비용 비교 편에서는, 데이터베이스 디스크 I/O 병목을 제거하고 백업 부하를 획기적으로 낮추기 위해 이미지 파일 원본은 Amazon S3 클라우드 분산 저장소에 안전하게 보관하고, DB 테이블에는 오직 가벼운 문자열 URL 정보만을 적재하여 소통하는 고해상도 아키텍처 기회비용을 객관적 지표와 함께 날카롭게 비교 해부해 드리겠습니다.

    오늘 6개 테이블 DDL 컴파일 과정에서 외래키 참조 관계(Foreign Key Constraint) 순서가 꼬여 자식 테이블 생성 실패 에러(Error 1215)를 겪으셨거나, CHECK 문 활용법이 아리송하시다면 당황하지 마시고 운영자 메일로 문의해주세요. 오늘도 안전하고 똑똑한 클라우딩 라이프 하세요. 감사합니다! 😉

    출처

    • 이현호. 실무 프로젝트로 완성하는 클라우드 환경에서 DB 구축과 웹 개발. 길벗캠퍼스. 2026.04. (5.2장 '의류 쇼핑 DB 구축', 134-141페이지 참조)
    • 이현호. "05장. 데이터베이스 구축_설명오디오.m4a" 설명 오디오 가이드 스크립트 기반 6대 테이블 비즈니스 정책 매핑, bcrypt 연동을 위한 passwd VARCHAR(255) 할당 이유 및 prod_size CHECK 제약조건 방어 메커니즘 대화록 완벽 반영.
    • MySQL Community Server Character Sets and DDL Rules (https://dev.mysql.com/doc/refman/8.0/en/create-table.html) 및 AWS RDS Engine Optimization Guide.

    자주 묻는 질문 (FAQ) 

    Q. 쇼핑몰 Customers 테이블 설계 시 패스워드 저장 컬럼 크기를 왜 VARCHAR(255)로 엄청나게 넓게 확보해야 하나요? 

    A. bcrypt 암호화 해싱을 원활히 지원하기 위해서입니다. 일반적인 비밀번호 입력값이 짧더라도 향후 실습에서 단방향 해시 솔트 처리를 거치면 60자 이상의 긴 암호화 텍스트로 고정 변환되어 데이터가 팽창하므로, 사전에 무손실 저장이 가능하도록 넉넉히 설계해야 합니다.

    Q. 장바구니 테이블 Carts의 상품 사이즈 속성에 걸려있는 CHECK 제약조건의 실무적인 가치는 무엇인가요? 

    A. 최후의 데이터 무결성 방어벽 역할을 수행합니다. 개발자의 코드 실수나 악의적인 API 해킹 침투로 인해 웹 브라우저나 백엔드 로직의 1차 필터링이 뚫리더라도, 데이터베이스 엔진 레벨에서 허용되지 않은 쓰레기 값(예: S, M, L 외의 무단 입력)의 삽입을 단칼에 거부해 줍니다.

    Q. Products 테이블의 prod_intro 컬럼 데이터 타입을 VARCHAR가 아닌 MEDIUMTEXT로 설정하여 활용하는 진짜 이유는 무엇인가요? 

    A. HTML 코드로 조직된 대용량 레이아웃 페이지를 통째로 수용하기 위함입니다. 쇼핑몰 상세 페이지는 화려한 CSS 스타일과 길게 늘어선 마크업 코드들로 가득하므로, 최대 16MB 텍스트를 무손실로 안전하게 적재 및 로딩할 수 있는 RDBMS의 특수 대용량 텍스트 장비를 채택하는 것입니다.