커머스 시스템을 설계하던 중, "상품 가격이 변동되면 과거의 주문 내역은 어떻게 유지되는가?"라는 문제에 직면함. 이를 해결하기 위한 데이터 보존 방식인 스냅샷 패턴을 학습함.
데이터베이스 설계에서 특정 시점의 상태를 그대로 복사하여 저장하는 방식을 의미함. 보통 DB 정규화는 중복을 피하기 위해 ID(외래키)만 저장하는 것을 권장하지만, 결제와 같은 증빙이 필요한 도메인에서는 당시의 데이터를 중복 저장하는 비정규화 방식인 스냅샷이 필수적임.
OrderItem 테이블이 Product 테이블의 id만 가짐.OrderItem 테이블이 id뿐만 아니라 price, name 컬럼을 직접 가짐.결과:
public void createOrder(Long productId, int quantity) {
// 1. 현재 시점의 상품 정보를 조회 (Source)
Product product = productRepository.findById(productId);
// 2. 주문 상세 객체를 생성할 때 '현재 가격'을 스냅샷으로 저장
OrderItem orderItem = OrderItem.builder()
.productId(product.getId())
.orderPrice(product.getPrice()) // 이 시점의 가격을 박제!
.productName(product.getName()) // 이 시점의 상품명을 박제!
.quantity(quantity)
.build();
// 3. 주문 저장
orderRepository.save(new Order(orderItem));
}