5월 12일 작업로그
1. 개념적 설계 (ERD 작업)
상품 개체

- 기존에 상품 개체 하나 정도에 카테고리 개체 하나 이렇게 있던 상태에서 장바구니와 옵션을 추가하겠다고 생각하며, 꽤 수정을 많이 하게 되었다.
- 우선 카테고리 테이블을 만들어, 쇼핑몰 안에 있는 모든 상품들을 카테고리 테이블 내의 범주에서 분류할 수 있고, 카테고리 ID 정도만 외래키로 두는 것을 생각하고 ERD를 그렸다.
- 옵션을 처음 만들었을 때는 상품 아래 속성에 바로 작성하였는데, 추후에 옵션의 종류(예: 색상/크기)와 종류에 따른 실제 상세 옵션/옵션값(예: 진청/청/하양, S/M/L/XL) 등이 존재할 수 있기에 각각을 테이블로 분류해야할 것 같다는 생각이 들었다 → 옵션 종류 테이블, 옵션 상세 테이블을 일단? 개체로 만들어두고 다시 상품을 먼저 완성하기로 했다.
- 옵션-상품 관계를 어떻게 해야할까? 하는 생각을 많이 했다. 처음에는 상품의 외래키 속성 정도면 충분할 것 같았는데? 그러면 사실 상품명/기본가격/제조업체 같은 내용의 중복이 많아진다. → 옵션-상품은 다대다 관계일거같아 테이블로 하나 빼는게 좋아보였다. 매핑 테이블 식으로 “상품 옵션 조합” 테이블을 만들었다.
- 쇼핑몰 블록/화면에 뜨는 상품하고, 실제 주문하는 상품이 다르기에(예: 청바지 → 검은 청바지 M) 상품 테이블과 또 별개로 실제 주문하는 상품(주문상품?)이 될 “상품 상세” 개체를 만들었다.
- 상품 상세 개체를 만든 후에는 상품 아래에 있던 재고 수량, 이미지, 판매량 등이 상품 상세 쪽, 즉 실제 판매되는 상품 쪽으로 옮겨가는게 좋을 것 같아 상품 상세쪽으로 속성을 옮겨 수정해주었다.
상품 관련 정리
- 상품: 대표 상품(청바지, 후드집업) 등의 정보 → 옵션 제외 공통적인 정보를 담아둠
- 상품 상세: 실제 판매되는 상품=장바구니에 들어가서 결제될 상품. (연한 청바지 S 같이) → 상품을 외래키로 가지고, 재고, 옵션에 따른 추가금, 판매량 등 판매 관련 실제 정보가 존재하고, 매핑 테이블을 통해 옵션과 조합될 개체
- 상품 옵션 조합: 상품상세와 옵션(상세값)을 각각 외래키로 가지는 매핑 테이블. 둘이 복합키를 구성.
- 카테고리: 상품(대표 상품/공통 상품)이 어느 카테고리에 속하는지 여부를 결정. 상품 테이블에서 외래키로 소유.
옵션 개체

- 큰 옵션 범주(사이즈/색상)과 안으로 들어가 세부적인 값을 가질 옵션 상세를 우선은 나누었다. → 현재 크기의 쇼핑몰? 단위에서는 사실 굳이 필요할까 싶긴했는데, 비즈니스 로직을 생각하면 색상 → 검정/하양 이렇게 선택하니까 큰 범주를 테이블로 빼두면 구현하는 것도 좋을 것 같았다.
- 약한 개체가 여전히 헷갈리긴하지만, 옵션상세가 단순히 옵션값으로만 구별된다기보다는 옵션종류+실제 그 옵션값 이렇게 분리되어야할 것 같아서 처음에는 복합키를 생각했는데 이래저래 구현하는 것 생각하고 외래키로 가져야하는거 생각하면 대리키를 두는게 좋을 것 같아 옵션ID라는 대리키를 두고 PK로 삼는게 좋아보여서 그렇게 ERD를 설계했다.
옵션 관련 정리
- 옵션 종류: 큰 옵션 범주. 예) 사이즈, 색상 …
- 옵션 상세: 종류 내의 세부적인 옵션. 예) S/M/L/XL, 카키, 검정, 하양
장바구니 개체

- 장바구니 자체는 사실 회원이 1:1로 소유하는 것이기에 굳이? 개체/테이블로 만들어야할까하는 생각이 들었는데 일단은…확장 가능성?도 있을 수 있고 해서 만들어보긴했는데 여전히 실제 필요할까? 싶긴하다.
- 장바구니 상품은 장바구니 안에 들어가는 상품의 데이터를 기록하기 위한 테이블/개체가 필요할 거라고 생각해 만들었는데..? 사실 처음에는 주문 상세같은 쪽에서 컬럼을 하나 두어 상태컬럼으로 장바구니 이런 식으로 두는 것도 방법이지 않을까?했는데 장바구니 특성상 실제 넣었다가 주문하지 않을 수도 있고 하기에 일단 분리하여 관리하는 쪽이 좋을 것 같았다.
- 장바구니 담았을 때의 가격도 일단 가지게 했는데 필요할지..? 상품상세ID를 이용해서 조인으로 가져올 수 있을 것 같긴한데..? 근데 또 주문마다 조인해서 가져오려면 양이 많아질 것 같아서 아직 고민이다.
장바구니 관련 정리
- 장바구니 종류: 실질적으로는 회원ID 1:1 매핑.
- 장바구니 상품: 장바구니 안에 담기는 상품들에 대한 정보. 수량이나, 상품 상세(실제 판매 상품), 담긴 장바구니(=회원 ID) 등이 존재하고, 이 모든걸 대리키(장바구니 상품 ID)로 관리. ⇒ 가격이 굳이 있어야할까…?는 아직 미정…
2. 논리적 설계
상품 논리적 설계
상품
상품 (상품ID(PK), 제조업체ID(FK), 상품명, 가격, 카테고리(FK), 이미지)
- 상품ID (INT): PK, NOT NULL, AUTO INCREMENT
- 제조업체ID (INT): FK, NOT NULL
- 상품명 (VARCHAR): NOT NULL
- 가격 (INT): NOT NULL
- 카테고리: FK, NOT NULL
- 이미지 (VARCHAR)
상품상세
상품상세 (상품상세ID(PK), 상품ID(FK), 재고수량, 추가금, 판매량, 이미지)
- 상품상세ID (INT): PK, NOT NULL, AUTO INCREMENT
- 상품ID: FK, NOT NULL
- 재고수량 (BIGINT): NOT NULL, DEFAULT 0
- 추가금 (BIGINT): NOT NULL, DEFAULT 0
- 판매량 (BIGINT): NOT NULL, DEFAULT 0
- 이미지 (VARCHAR)
상품옵션 조합
상품옵션 조합 (상품상세ID(PK, FK), 옵션ID(PK,FK))
- 상품상세ID (INT): PK, FK, NOT NULL
- 옵션ID (INT): PK, FK, NOT NULL
카테고리
카테고리 (카테고리ID(PK), 카테고리명)
- 카테고리ID (INT): PK, NOT NULL, AUTO INCREMENT
- 카테고리명 (VARCHAR): NOT NULL
제조업체
제조업체 (업체번호(PK), 업체명, 소유자)
- 업체번호 (INT): PK, AI, NOT NULL
- 업체명 (VARCHAR): NOT NULL
- 소유자 (VARCHAR)
장바구니 논리적 설계
장바구니
장바구니 ( 회원ID(PK, FK) )
장바구니 상품
장바구니 상품 (장바구니상품ID(PK), 장바구니ID(FK), 상품상세ID(FK), 담은수량, 가격)
- 장바구니 상품ID (INT): PK, NOT NULL, AUTO INCREMENT
- 회원ID (INT): FK
- 상품상세ID (INT): FK
- 담은수량 (BIGINT): NOT NULL, DEFAULT 1
- 가격 (BIGINT): NOT NULL
옵션 논리적 설계
옵션 종류
옵션 종류 (옵션 종류ID(PK), 옵션 종류명)
- 옵션 종류ID (INT): PK, NOT NULL, AUTO INCREMENT
- 옵션 종류명 (VARCHAR): NOT NULL
옵션 상세
옵션 상세 (옵션상세ID(PK), 옵션 종류ID(FK), 옵션값)
- 옵션상세ID (INT): PK, NOT NULL, AUTO INCREMENT
- 옵션 종류ID (INT): FK
- 옵션값 (VARCHAR): NOT NULL
- 양이 많아서 토글로 정리합니당
- ERD 짜면서 고민했던 부분들이라 슥슥 작성하긴했는데 NOT NULL 외에 UNIQUE 등 다른 제약을 걸 부분들이 있을 수도 있을 것 같다는…생각이 들긴합니다. (VARCHAR 제한?)
3. SQL 설정
깃허브 + 스프링 프로젝트 사용해서 일단 협업을 진행할 생각이었어서 sql 코드 공유를 어떻게 할 지? 찾아봤는데 resources 아래에 application.yaml 파일을 잘 설정하고 data.sql, schema.sql에 sql 코드 작성하면 잘 돌릴 수 있을 것 같았다.
사용자명하고 비밀번호는 올리면 안되니까 application-local.yaml로 분리하는 방식으로 가져가고, application.yaml 파일 설정한 후에 깃허브에 data.sql, schema.sql 파일까지 올려서 설정하였다.
이렇게 하면 schema.sql에 DDL 작성하여서 공유하면 각자 노트북에서 이걸 돌려도 같은 결과를 얻을 수 있을 것 같아서 이런식으로 진행하면 좋을 것 같았다. data.sql에 더미 데이터 관련 insert 쿼리 등을 올리면 되는 식이다.
application.yaml
spring:
profiles:
active: local
application:
name: {이름}
sql:
init:
mode: always
jpa:
defer-datasource-initialization: true
hibernate:
ddl-auto: none
properties:
show_sql: true
format_sql: true
highlight_sql: true
application-local.yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/{스키마이름}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true
username: '사용자이름'
password: '비밀번호'
driver-class-name: com.mysql.cj.jdbc.Driver