본문 바로가기
Project

[newsfeed] 댓글과 게시글의 '좋아요' 기능, 어떤 식으로 구현하는게 좋을까?

by 어떻게말이름이히힝 2024. 12. 30.

프로젝트 상의 게시글(Post)과 댓글(Comment)에 각각 좋아요 기능이 구현되어야 했다.

첫 번째 구현한 방법은 아래 ERD 다이어그램과 같다.

 

 

좋아요 기능이 유저-게시글 / 유저-댓글의 형태로 중복이 되지 않게 하나만 존재하게 하는 방법에 대해서도 고민 했는데, 처음에는 검증을 하려고 생각했으나 더 좋은 방법이 있었다. 

 

다중 컬럼을 아래 코드와 같이 unique 제약조건을 사용해 묶었다. 

여기서의 문제점은 굳이 UniqueConstraint를 사용할 필요가 없었던 것이다.

Service에서 해당되는 행이 존재하면 삭제하는 동작이 있기 때문이다.

@Table(uniqueConstraints ={
    @UniqueConstraint(name = "user_like_comment",
    columnNames = {
            "user_id",
            "comment_id"
    })
})
@Entity
@NoArgsConstructor
@Getter
public class CommentLike {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @ManyToOne
    @JoinColumn(name = "comment_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Comment comment;

    public CommentLike(User user, Comment comment) {
        this.user = user;
        this.comment = comment;
    }
}

 

 

프로젝트가 끝난 후, 강의를 듣다가 다른 방법을 찾을 수 있었는데 바로 조인 전략이었다.

Like 엔티티를 생성한 후 type 필드를 추가하여 게시글에 달린 좋아요와 댓글의 달린 좋아요를 구분하는 방법이었다.

 

두 방법에 대한 차이

기준 1번 별도 테이블만들기(PostLike, CommentLike) 2번 Like 테이블에 type 구분
데이터 구조 데이터 구조가 이해하기 쉬움.
특정 도메인에 집중하여 유지보수 용이.
데이터베이스 구조가 단순해짐.
통합적으로 구성되어 있어 한 곳에서 관리 가능.
type 값에 따라 다른 엔티티와 연관되므로 데이터 무결성이 깨질 위험 있음.
성능 특정 도메인 쿼리 실행 시 불필요한 데이터를 스캔하지 않아 성능이 좋을 수 있음
인덱스 최적화도 각 테이블에 맞게 설계 가능
좋아요 조회 시 type에 대한 필터가 필요하므로 성능이 저하될 가능성이 있음
하나의 테이블에 모든 좋아요가 저장되어 데이터 양이 많아질수록 조회 성능 저하될 수 있음.
확장성 쉽게 확장할 수 있음 만약 게시글의 좋아요와 댓글의 좋아요가 다른 특정 속성이 필요하다면 확장이 어려움
쿼리 복잡도 조인 또는 다중쿼리가 필요함 단일쿼리로 가능
테이블 관리 관리해야할 테이블 많음 단일 테이블

 

 

끝으로 보통의 대형 SNS(페북, 인스타, x)의 경우는 데이터 구조 직관성, 성능 최적화, 확장 가능성 때문에 1번 방법을 선호하는 편이라고 한다.