기본적인 댓글 알고리즘에 대해서 살펴보겠습니다 :)
첫 번째로 댓글을 구현하는데 가장 많이 사용하는 방법은 "인접 목록 방식"입니다.
댓글의 아이디를 참조하는 parent_id 칼럼을 추가하는 방식으로써 하나의 테이블만으로 댓글 기능을 구현합니다.
이해를 위하여 아래의 테이블을 예시로 들겠습니다.
CREATE TABLE dbo.COMMENT_TEST
(
comment_id bigint not null, -- 댓글 아이디(pk)
parent_id bigint null, -- 부모 아이디
comment nvarchar(500) not null, -- 댓글 내용
comment_date datetime not null, -- 작성 일자
author varchar(20) not null -- 작성한 사람
)
ALTER TABLE dbo.COMMENT_TEST ADD CONSTRAINT PK__COMMENT_TEST__COMMENT_ID PRIMARY KEY (comment_id)
INSERT INTO dbo.COMMENT_TEST VALUES (1,NULL,N'데이터베이스 어려운가요?',getdate(),'ssh9308');
INSERT INTO dbo.COMMENT_TEST VALUES (2,1,N'열심히 공부하시면 어렵지 않을겁니다!',getdate(),'kyj9787')
INSERT INTO dbo.COMMENT_TEST VALUES (3,2,N'친절한 답변 감사합니다!',getdate(),'ssh9308')
INSERT INTO dbo.COMMENT_TEST VALUES (4,1,N'SQL 안티패턴 책을 한번 봐보세요',getdate(),'korea1993')
INSERT INTO dbo.COMMENT_TEST VALUES (5,4,N'어려운 내용은 아닐까요?',getdate(),'mansae4433')
INSERT INTO dbo.COMMENT_TEST VALUES (6,4,N'그책은 입문서로는 좀 어렵지 않을까요?',getdate(),'respond9977')
INSERT INTO dbo.COMMENT_TEST VALUES (7,6,N'입문서로는 좀 어려울수 있겠군요 ㅜ',getdate(),'youngboys123')
첫 번째 글 "데이터베이스 어려운가요?"의 comment_id를 1이라고 두면, 해당 댓글에 대한 답글인
"열심히 공부하시면 어렵지 않을 겁니다!"의 comment_id 가 2가 되고, comment_id = 1에 대한 답글이 되므로,
parent_id = 1 이 되게 됩니다.
그럼 이러한 인접 목록 방식을 실제 서비스에서 사용하기 위해 댓글의 답글을 불러오는
쿼리는 어떤 식으로 작성해야 할지 아래의 쿼리를 보면서 이해해보도록 하겠습니다.
댓글의 첫 번째 답글을 가져오기 위해서는 JOIN이나 SEBQUERY를 사용할 수 있습니다.
1. JOIN 을 이용한 방법
SELECT c2.* FROM dbo.COMMENT_TEST c1 WITH(NOLOCK)
LEFT OUTER JOIN dbo.COMMENT_TEST c2 WITH(NOLOCK) ON c1.comment_id = c2.parent_id
WHERE c1.comment_id = 1
2. SUBQUERY를 이용한 방법
SELECT
*
FROM dbo.COMMENT_TEST WITH(NOLOCK)
WHERE comment_id IN (SELECT
comment_id
FROM dbo.COMMENT_TEST WITH(NOLOCK)
WHERE parent_id = 1
)
그럼 답글에 대한 답글을 가져오려면 어떤 식으로 조회해야 할까요?
조인을 한번 더 걸어서 쿼리 해주는 방법이 있습니다.
SELECT c3.* FROM dbo.COMMENT_TEST c1 WITH(NOLOCK)
LEFT OUTER JOIN dbo.COMMENT_TEST c2 WITH(NOLOCK) ON c1.comment_id = c2.parent_id
LEFT OUTER JOIN dbo.COMMENT_TEST c3 WITH(NOLOCK) ON c2.comment_id = c3.parent_id
WHERE c1.comment_id = 1
그럼 자연스럽게 해당 답글에 대한 답글은 한 번 더 조인을 통해서 가져올 수 있음을 유추해볼 수 있습니다.
SELECT c4.* FROM dbo.COMMENT_TEST c1 WITH(NOLOCK)
LEFT OUTER JOIN dbo.COMMENT_TEST c2 WITH(NOLOCK) ON c1.comment_id = c2.parent_id
LEFT OUTER JOIN dbo.COMMENT_TEST c3 WITH(NOLOCK) ON c2.comment_id = c3.parent_id
LEFT OUTER JOIN dbo.COMMENT_TEST c4 WITH(NOLOCK) ON c3.comment_id = c4.parent_id
WHERE c1.comment_id = 1 and c4.comment_id IS NOT NULL
하지만, 대부분의 서비스 사이트에서는 수많은 댓글이 달리게 되고 해당 댓글에 대한 답글도 무수히 많이 존재합니다.
SQL 쿼리에서 조인 회수는 미리 고정되어야 하기 때문에 몇 번의 조인이 합당할지 알기도 어렵습니다.
또한, 너무 많은 조인 횟수 때문에 성능에 저하를 가져올 수도 있습니다.
위와 같은 문제점을 해결하고자 다음 포스팅에서는 댓글 알고리즘의 하나의 경로 열거(Path Enumeration) 방법에 대해
알아보겠습니다 :)
경로 열거 방식이 궁금하다면 - [Algorithm] 경로 열거 방식
'알고리즘' 카테고리의 다른 글
댓글 알고리즘 - 중첩집합(3) (2) | 2021.07.22 |
---|---|
댓글 알고리즘 - 중첩집합(2) (0) | 2021.07.22 |
댓글 알고리즘 - 중첩집합(1) (4) | 2021.07.22 |
댓글 알고리즘 - 경로열거(Path Enumeration) (0) | 2021.07.22 |