인프런 커뮤니티 질문&답변
반정규화
해결된 질문
작성
·
42
·
수정됨
0

회원 조회 쿼리는 N+1 문제라고 하시고 넘어가셨는데 회원 이메일은 반정규화 대상에 포함이 안된 이유가 뭔가요? 주문 상품에 비해 간단해서 그런가요?
제 기존 프로젝트에 강의 내용을 적용하고 있는데 저는 dto 변환 메서드 때문에 회원, 주문상품, 상품 테이블까지 조회 쿼리가 나가고 있는데 3개다 그냥 주문 테이블에 컬럼을 추가해서 반정규화 하는게 좋을까요? 현재 주문은 한번 생성되면 status 빼고는 데이터가 변경될 일이 없습니다.
답변 2
0
안녕하세요 에어님 좋은 질문 해주셔서 감사합니다!!
1. 왜 회원 이메일은 반정규화 대상에 포함되지 않았나요?
회원 정보 조회는 단순한 1:1 JOIN으로 해결할 수 있습니다. orders.member_id = members.id 형태의 조인은 인덱스만 잘 걸려있으면 성능 부담이 크지 않습니다. 반면 주문 아이템 개수는 매번 order_items 테이블 전체를 불러와서 COUNT를 해야 했기 때문에 훨씬 더 심각한 병목이었습니다.
회원 이메일은 변경될 가능성이 있습니다. 사용자가 이메일을 수정하면 반정규화된 모든 주문 데이터도 함께 업데이트해야 하는 부담이 생깁니다. 반면 주문 아이템 개수는 주문이 생성된 이후에는 거의 변하지 않습니다(상태 변경은 있어도 아이템 개수 자체는 고정).
정합성 관리 비용 대비 성능 개선 효과를 따졌을 때, 회원 이메일 반정규화는 효율이 낮다고 판단해서 그렇게 결정 했습니다!
2. 본인 프로젝트에 어떻게 적용해야 할까요?
주문이 생성되면 status 외에는 변경이 없다고 하셨는데, 이 경우 반정규화를 고려해볼 만합니다. 하지만 모든 것을 반정규화하는 건 신중해야 합니다.
반정규화를 적용하면 좋은 경우는 다음과 같습니다. 조회 빈도가 매우 높은 데이터인가요? 주문 목록 조회 시 매번 필요한 정보라면 반정규화 고려 대상입니다. 데이터가 거의 변경되지 않나요? 주문 확정 후 변경이 없다면 동기화 부담이 적습니다. N+1 문제가 심각한가요? 매번 연관 테이블을 조회해야 한다면 반정규화로 큰 효과를 볼 수 있습니다!
반정규화하지 않는 게 나은 경우도 있습니다. 자주 변경되는 데이터는 피하세요. 회원 정보처럼 수정이 빈번하면 동기화 로직이 복잡해집니다. 단순 JOIN으로 해결 가능한 경우도 굳이 반정규화할 필요 없습니다. 인덱스만 잘 걸면 충분합니다!
구체적인 적용 방안을 제안해드리자면, 주문 상품 이름이나 가격은 반정규화를 고려해볼 만합니다. 주문 목록에서 "무엇을 샀는지" 보여줘야 하는데, 매번 상품 테이블을 조회하는 건 비효율적입니다. 주문 당시의 상품명과 가격을 주문 테이블이나 주문 아이템 테이블에 스냅샷으로 저장하는 게 일반적입니다. 실제로 커머스에서는 주문 확정 시점의 가격을 보존해야 하므로 이미 이렇게 설계하는 경우가 많습니다.
회원 정보(이메일, 이름 등)는 반정규화보다는 인덱스 최적화로 해결하세요. 또는 통계성 데이터가 필요하다면 강의처럼 별도 통계 테이블을 만들어 배치로 처리하는 방법도 좋을 것 같습니다!!
좋은 질문 감사합니다!
0
안녕하세요, 인프런 AI 인턴입니다.
에어님께서 문의하신 내용을 바탕으로 설명드리겠습니다.
회원 이메일이 반정규화 대상에 포함되지 않은 이유는 여러 가지가 있을 수 있습니다. 일반적으로 반정규화를 고려할 때, 조회 성능을 개선하기 위해 데이터 중복을 감수하려는 경우가 많습니다. 회원 이메일은 비록 간단한 정보일 수 있지만, 주문과 같은 주요 비즈니스 로직에 비해 중요도가 낮다고 판단되어 반정규화 대상에서 제외되었을 수 있습니다. 또한, 이메일 주소가 변경될 가능성이 있는 반면, 주문은 status를 제외하고 변경될 일이 없으므로, 지속적으로 일관성을 유지하는 것이 더 중요할 수 있습니다.
기존 프로젝트에 DTO 변환 메서드로 인해 여러 테이블을 조회하고 있다면, 반정규화를 통해 성능을 향상시킬 수 있습니다. 그러나 이런 변화는 데이터베이스 설계에 큰 영향을 줄 수 있으므로 신중하게 결정해야 합니다. 특히, 주문 테이블에 컬럼을 추가하여 회원, 주문상품, 상품 데이터를 반정규화할 경우, 데이터 일관성 관리가 어려워질 수 있습니다. 변경 가능성이 낮은 데이터라 하더라도 일관성을 유지하는 것이 우선임을 잊지 말아야 합니다.
주문 정보가 생성 후 변경되지 않는다는 점을 고려할 때, 가장 빈번하게 조회되는 데이터를 중심으로 반정규화를 고려해 보세요. 하지만 데이터 무결성과 유지보수 면에서의 trade-off를 항상 명심하시길 권장드립니다. 반정규화는 성능 측면에서 유리할 수 있지만, 데이터의 일관성과 무결성을 저하시킬 수도 있으므로, 필요성과 우선순위를 따져보시기 바랍니다.
도움이 되셨기를 바랍니다! 다른 궁금한 점이 있으시면 언제든지 문의해주세요.
Spring Data JPA - Query Methods: Projections
Spring Data JPA - Query Methods: Using @Query




