강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

염경호님의 프로필 이미지
염경호

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

요구사항 분석

도메인 설계에 대한 고민

작성

·

48

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]

erd 설계를 하다가 스스로 의문이 조금 들어서 질문드립니다.

image.png

현재 다음과 같은 앱을 구상하고 있습니다. AI 모델과 연동해서 추천 시스템을 생각 중인데 도메인 설계에 대해서 궁금한 부분이 생겨서 질문드립니다.

package forpracticejunbao.junbaoprac_be.recommend.domain;

import forpracticejunbao.junbaoprac_be.user.domain.User;
import forpracticejunbao.junbaoprac_be.common.util.BaseEntity;
import jakarta.persistence.*;
import lombok.*;

import java.util.ArrayList;
import java.util.List;

@Table(name = "recommend")
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Recommend extends BaseEntity {
    @Id
    @Column(name = "recommend_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;


    @OneToMany(mappedBy = "recommend",cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private List<RecommendClusterOption> recommendClusterOptions = new ArrayList<>();

    @OneToMany(mappedBy = "recommend",cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private List<RecommendValueOption> recommendValueOptions  = new ArrayList<>();

    @OneToMany(mappedBy = "recommend",cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private List<RecommendResult> results = new ArrayList<>();

    public void updateRecommendClusterOptions(List<RecommendClusterOption> recommendClusterOptions) {
        if (this.recommendClusterOptions != null) {
            this.recommendClusterOptions.clear();
            this.recommendClusterOptions.addAll(recommendClusterOptions);
        } else {
            this.recommendClusterOptions = recommendClusterOptions;
        }
    }

    public void updateRecommendValueOptions(List<RecommendValueOption> recommendValueOptions) {
        if (this.recommendValueOptions != null) {
            this.recommendValueOptions.clear();
            this.recommendValueOptions.addAll(recommendValueOptions);
        } else {
            this.recommendValueOptions = recommendValueOptions;
        }
    }



}
  1. Recommend 클래스를 만들고, ClusterOption(클러스터 선택)과 ValueOption(계절, 요일 등등)을 일대다 다대일로 풀고자 했는데 이 두가지 엔티티가 크게 다르지 않은 것 같아서 그냥 하나로 합치는게 좋을지(그냥 enum으로만 구분) 아니면 의미적으로 좀 다르기 때문에 구분하는게 좋을지 궁금합니다.(클러스터 선택과 계절 선택은 하나만 선택 가능, 나머지는 하나 이상 선택 가능 조건이기에 클러스터와 계절을 도메인으로 묶을지도 살짝 고민이 되는 것 같습니다..)

  1. 결과를 RecommendResult로 보여주고자하는데(ai 추천 받은 top 5값에 대한 스팟 정보 제공 목적) 괜찮은 설계일지 궁금합니다.

  2. init.sql을 통해 클러스터, 계절, 요일 등 초기값들을 insert 해주고, spot 정보는 csv 파일로 부터 읽어오도록 구현하고 있는데(@PostConstruct, implementation 'com.opencsv:opencsv:5.5' 이용) 실제로 이런 설계에서 초기값을 주입하고 이후 로직 구현하는게 실무적으로 일반적인 방식인지 궁금합니다..!

     

    긴 글 읽어주셔서 감사합니다.

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

염경호님, 도메인 설계에 대한 고민에 대해 몇 가지 생각을 공유드리겠습니다.

  1. 클러스터 옵션과 값 옵션 클래스 통합 여부: 두 엔티티가 비슷한 역할을 한다면 하나로 통합하고, enum 등을 사용해서 구분하는 것이 좋을 수 있습니다. 그러나 각 옵션이 서로 다른 비즈니스 로직을 가지고 있거나 앞으로 확장될 가능성이 높다면, 개별적으로 유지하는 것도 고려해 볼 수 있습니다.

  2. RecommendResult 설계: ai 추천 결과를 저장하는 RecommendResult 설계는 적절한 방식으로 보입니다. 추천 결과는 변화할 수 있으며, 이를 독립된 엔티티로 관리하는 것은 유연성을 제공합니다. 추가적인 속성이나 메타데이터가 필요할 경우, 확장하기도 수월할 것입니다.

  3. 초기값 주입 및 로직 구현 방식: 실무적으로 init.sql을 통해 초기 값을 주입하고 CSV를 통해 데이터 읽어오는 방식은 자주 사용됩니다. 이는 데이터베이스 초기화 및 표준 데이터를 준비하는 데 유리합니다. 또한, CSV 파일을 활용한 데이터 읽기 스크립트를 통한 초기 세팅은 효율적이지만, 데이터 양이 많을 경우 성능을 고려하여 적절한 방식으로 튜닝이 필요할 수 있습니다.

도움이 되었길 바랍니다. 질문이 있으시면 언제든지 다시 말씀해주세요. 감사합니다.

이미지 출처: Link to source

염경호님의 프로필 이미지
염경호

작성한 질문수

질문하기