
현재 팀 프로젝트에서 모놀리식 아키텍처 기반 DDD(Domain-Driven Design) 구조로 설계를 진행하고 있다.
그 과정에서 UUID, PK, FK, Index 개념이 헷갈렸던 부분을 정리해보았다.
MSA가 아닌 모놀리식 구조이지만,
도메인 중심으로 레이어를 분리하는 DDD 구조를 채택했다.
order
├── domain
│ ├── Order
│ ├── OrderItem
│ └── repository
├── application
│ └── OrderService
├── infrastructure
│ └── OrderRepositoryImpl
└── presentation
└── OrderController
기존 방식은 보통:
id BIGINT AUTO_INCREMENT
이번 프로젝트에서는:
id UUID
예시:
550e8400-e29b-41d4-a716-446655440000
| 컬럼 | 설명 |
|---|---|
| order_id (PK, UUID) | 주문 고유 ID |
| order_status | 주문 상태 |
| total_price | 총 금액 |
Order는 하나의 Aggregate Root이다.
| 컬럼 | 설명 |
|---|---|
| order_idx (PK, UUID) | 주문 상세 고유 ID |
| order_id | 주문 참조용 |
| menu_id | 메뉴 ID |
| quantity | 수량 |
| subtotal_price | 소계 금액 |
처음 가졌던 의문:
menu_id를 PK로 쓰면 안 되나?
한 주문에 같은 메뉴가 여러 번 들어갈 수 있다.
| order_id | menu_id | option |
|---|---|---|
| O1 | M1 | 얼음많이 |
| O1 | M1 | 얼음적게 |
menu_id는 고유하지 않다.
한 주문에는 여러 개의 주문 상세가 존재한다.
| order_id | menu_id |
|---|---|
| O1 | M1 |
| O1 | M2 |
order_id 역시 중복된다.
OrderItem의 각 행을 고유하게 식별하기 위해
별도의 PK(UUID)를 둔다.
order_idx UUID PRIMARY KEY
이 값은:
즉,
PK는 "고유 식별자"
Index는 "검색 속도 향상 도구"
PK는 기본적으로 인덱스를 포함한다.
복합 PK 예시:
PRIMARY KEY (order_id, menu_id)
문제점:
단일 PK:
order_idx UUID PRIMARY KEY
장점:
처음에는 이렇게 생각했다:
"같은 메뉴를 여러 번 넣기 위해 PK를 따로 둔 건가?"
하지만 실제 이유는:
OrderItem이라는 '엔티티 자체'를 고유하게 식별하기 위함이었다.
DDD에서는
테이블이 아니라 도메인 객체를 기준으로 설계해야 한다는 점을 배웠다.
이번 설계를 통해 느낀 점은:
DB 중심 사고가 아니라
도메인 중심 사고로 전환하는 것이
DDD의 핵심이라는 것.
앞으로는 테이블 구조보다
이 객체의 책임과 경계를 명확히 하기 위해서
"이 객체는 왜 존재하는가?"를 먼저 고민하려 한다.