Spring Boot

대댓글(Nested comments) 기능 구현 방식

sounglikane 2024. 12. 5. 16:16

Single Table

  1. 자기 참조 관계(Self-Referential Relationship)
    @Entity
    public class Comment {
        @Id
        @GeneratedValue
        private Long id;
        
        private String content;
        
        @ManyToOne
        private Comment parentComment;
        
        @OneToMany(mappedBy = "parentComment")
        private List<Comment> childComments;
    }
    장점:
    • 구현이 간단함
    • 직관적인 객체 지향 설계
    • 댓글 트리를 쉽게 탐색 가능
    • 중간 깊이의 중첩에 적합
    한계:
    • 매우 깊은 댓글 트리에서는 비효율적
    • 재귀 쿼리가 까다로울 수 있음
    • 깊게 중첩된 댓글에서 성능 저하
    • N+1 쿼리 문제 발생 가능
  2. 중첩 집합(Nested Set)
    @Entity
    public class Comment {
        @Id
        @GeneratedValue
        private Long id;
        
        private String content;
        
        @Column(name = "left_value")
        private Long left;
        
        @Column(name = "right_value")
        private Long right;
        
        private Integer depth;
    }
    장점:
    • 읽기 작업에 매우 효율적
    • 하위 트리를 빠르게 검색 가능
    • 부모/자식 찾기를 상수 시간에 수행
    • 거의 변하지 않는 정적 댓글 구조에 적합
    한계:
    • 댓글 삽입 및 삭제가 복잡함
    • 수정 시 전체 트리 재균형 필요
    • 증분 업데이트 구현이 어려움
    • 개발자에게 직관적이지 않음
    • 왼쪽 및 오른쪽 값 유지 오버헤드
  3. 구체화된 경로(Materialized Path)
    @Entity
    public class Comment {
        @Id
        @GeneratedValue
        private Long id;
        
        private String content;
        
        @Column(name = "path")
        private String ancestorPath;
        
        private Integer level;
    }
    장점:
    • 유연하고 쿼리하기 쉬움
    • 계층적 관계 구현이 간단
    • 전체 댓글 브랜치 검색에 효율적
    • 깊이 제한 쉽게 추가 가능
    • 중간 정도로 변경되는 댓글 구조에 적합
    한계:
    • 경로 문자열이 길어질 수 있음
    • 매우 깊은 트리에서 성능 문제
    • 쿼리를 위해 문자열 조작 필요
    • 깊은 중첩으로 인덱스 크기 증가

중간 Table

@Entity
public class Comment {
    @Id
    @GeneratedValue
    private Long id;
    private String content;
}

@Entity
public class Thread {
    @Id
    @GeneratedValue
    private Long id;
    
    @ManyToOne
    private Comment parentComment;
    
    @ManyToOne
    private Comment childComment;
    
    private Integer depth;
}

장점:

  • 가장 유연한 접근 방식
  • 복잡한 관계 추적 가능
  • 관계에 대한 추가 메타데이터 쉽게 추가
  • 매우 복잡한 댓글 계층 처리 가능

한계:

  • 구현이 가장 복잡함
  • 상당한 성능 오버헤드
  • 더 복잡한 쿼리
  • 높은 저장 요구사항
  • 쓰기 작업의 복잡성 증가

권장 Matrix

접근 방식 적합한 경우 피해야 할 경우
자기 참조 관계 (Single Table) - 중간 깊이 중첩
- 간단한 Application
- 동적 댓글 구조
- 극도로 깊은 댓글 트리
- 성능에 민감한 애플리케이션
중첩 집합 (Single Table) - 정적 댓글 트리
- 읽기 중심 애플리케이션
- 수정이 드문 경우
- 자주 업데이트되는 댓글
- 실시간 댓글 시스템
구체화된 경로 (Single Table) - 중간 정도 변경되는 구조
- 브랜치 빠른 검색 필요
- 깊이 제한 댓글
- 극도로 깊은 트리
- 복잡한 중첩이 있는 시스템
중간 Table - 복잡한 관계 추적
- 광범위한 메타데이터 필요
- 고도로 맞춤화된 시스템
- 간단한 댓글 시스템
- 성능에 민감한 애플리케이션

권장 사항

대부분의 Spring Boot Application에서는 자기 참조 관계 방식을 추천합니다. 그 이유는:

  • 단순성
  • 구현 용이성
  • 일반적인 사용 사례에서의 좋은 성능
  • 대부분의 댓글 시스템에 적합한 유연성