본문 바로가기
Back-End

[DB & JPA] 무한 스크롤 계층형 댓글 구현하기

by kong_tae 2025. 5. 24.

들어가며

일반적으로 많은 어플리케이션에서 페이지네이션보다는 스크롤 형식의 댓글을 구현하며, 이와 함께 대댓글 기능을 포함하고 있습니다.

저 역시 좋은 기회로 작은 사전 과제에서 이러한 기능을 고민하고 구현하는 경험을 할 수 있게 되어서 해당 과정을 공유하고자 글을 작성하게 되었습니다.

 

요구사항

댓글은 하나의 요청(스크롤)에 5개의 댓글을 불러와야합니다. 또한, 대댓글 기능을 지원해야합니다.

기존 요구사항은 위와 같이 어떻게 보면 단순하게 무한 스크롤을 통해 댓글을 5개씩만 불러오면 되는 것이 아닌가? 라고 생각할 수 있을 것입니다. 하지만 아래와 같은 부분을 함께 고민하면 좋을 것 같습니다.

 

1. 앞서 있던 댓글에 대댓글을 작성하면, 해당 대댓글은 어느 시점에 보여야 하는가?

2. 만약, 해당 대댓글이 앞선 댓글 다음에 보여야 한다면, 무한 스크롤을 진행할 때 정렬 기준을 어떻게 해야하는가?

3. 댓글 A - A의 대댓글 B - B의 대댓글 C 와 같이 계층형 구조가 이루어진다면 어떻게 해야하는가?

 

처음 요구사항은 단순하게 해석할 수 있지만, 이러한 추가적으로 고민해야할 부분이 생기게 되었습니다.

이를 해결하고자 했던 과정을 순차적으로 보여드리겠습니다.

 

테이블 설계

초기 테이블은 다음과 같습니다.

이렇게 설계하게 되면, 대댓글 기능을 구현할 수 있게됩니다. 댓글 A의 대댓글을 작성하고자 하면, 댓글 B는 parent_id 로 댓글 A의 아이디를 참조하는 것으로 간단하게 구현할 수 있게 됩니다.

 

하지만, 문제는 이를 사용자에게 보여주고 할 때입니다. 만약 커서 기반 페이지네이션에서 커서를 ID 컬럼으로 결정하게 된다면, 다음과 같은 왼쪽 그림과 같은 상황이 발생할 것입니다. 하지만 저희가 생각하는 이상적인 댓글의 모습은 오른쪽과 같을 것입니다.

 

 

따라서, ID를 커서로 결정하게 된다면 오른쪽과 같은 순서로 댓글을 전달할 수 없을 것입니다.

 

테이블 변경 하기

오른쪽 그림을 (parent_id, id) 순서로 한번 나열해보겠습니다. 

(null, 1) -> (1, 4) -> (null, 2) -> (null, 3) -> (3, 5) . . .

왠지, DFS와 같은 느낌이 들었습니다. 즉, 계층을 나타낼 수 있도록 테이블을 설계하면 이상적인 순서를 보존할 수 있을 것 같았습니다.

따라서, path(varchar) 컬럼을 추가하게되었습니다. 이를 통해 다음 처럼 path를 나타내도록 하였습니다.

 

이를 통해 단순히 Path 컬럼을 커서로 하여 댓글을 계층식으로 조회할 수 있게 되었습니다.

이를 위해 댓글 작성 API 에서는 path 를 자신의 ID로 설정하고, 대댓글 작성 API에서는 path를 부모 PATH + "." + 자신의 ID로 설정하도록 수정하였습니다.

 

이러한 방식을 통해 앞서 언급한 요구사항을 만족할 수 있게 되었습니다.

 

마치며

다만, 제가 생각하기에 저의 방식에는 단점이 존재하였습니다. 이는 바로, 데이터의 크기입니다. 만약 ID와 같은 bigint 형식의 인덱스를 하나의 페이지에 담을 때에는 varchar 방식에 비해 정말 많은 데이터를 담을 수 있을 것입니다. 이는 인덱스 탐색에서 bigint 형식이 varchar 방식에 비해 동일한 행을 갖고 있더라도, 작은 트리 높이를 보장하는 것을 의미합니다. 즉, 검색의 성능이 떨어진다는 것입니다. 

댓글의 데이터가 늘어나게 되면, ID의 값도 함께늘어나고 이는 path의 길이가 길어지게 되는 것을 의미할 것입니다. 따라서 제가 선택한 방식은 결과적으로는 수 많은 댓글이 달리는 상황에서는 또 다른 방식으로 변경이 필요할 것입니다!

댓글