자기 참조 테이블에서 댓글 중첩 깊이 제한하는 방법

발행: (2025년 12월 14일 오전 08:55 GMT+9)
3 min read
원문: Dev.to

Source: Dev.to

Introduction

댓글 시스템(예: Reddit이나 기술 블로그)을 자체 참조 관계로 구축할 때, 각 댓글은 다른 댓글을 부모로 참조할 수 있습니다. 이는 무한 중첩을 가능하게 하지만, 깊은 재귀는 UI 가독성과 성능에 악영향을 줍니다. 흔히 요구되는 것이 중첩 깊이를 제한하는 것(예: 최대 5단계)입니다.

Standard Adjacency List Model

CREATE TABLE comment (
    id BIGINT PRIMARY KEY,
    parent_id BIGINT, -- References id
    content TEXT
);

이 스키마에서 깊이 제한을 강제하려면 매 삽입 시 재귀 CTE를 사용해야 하는데, 이는 비용이 많이 듭니다.

Database Schema Update

중첩 레벨을 명시적으로 저장하기 위해 depth(또는 level) 컬럼을 추가합니다.

CREATE TABLE comment (
    id BIGINT PRIMARY KEY,
    parent_id BIGINT,
    content TEXT,
    depth INT DEFAULT 1 -- 1 for root comments
);

Application Logic (JPA Example)

새 댓글을 만들 때는 부모 댓글의 깊이만 확인하면 됩니다.

Steps

  1. 부모 댓글을 조회합니다.
  2. 깊이 검증: parent.depth >= MAX_DEPTH이면 답글을 거부합니다.
  3. 자식 깊이 설정: child.depth = parent.depth + 1.

Best‑Practice Code (Spring Boot / Java)

@Service
@RequiredArgsConstructor
public class CommentService {

    private final CommentRepository commentRepository;
    private static final int MAX_DEPTH = 5;

    @Transactional
    public void addReply(Long parentId, String content) {
        // 1. Fetch Parent
        Comment parent = commentRepository.findById(parentId)
            .orElseThrow(() -> new EntityNotFoundException("Parent not found"));

        // 2. Validate Depth
        if (parent.getDepth() >= MAX_DEPTH) {
            throw new IllegalArgumentException(
                "Comments cannot be nested deeper than " + MAX_DEPTH + " levels.");
        }

        // 3. Create Child
        Comment reply = Comment.builder()
            .content(content)
            .parent(parent)
            .depth(parent.getDepth() + 1) // Calculate depth immediately
            .build();

        commentRepository.save(reply);
    }
}

Read Performance

깊이가 저장되어 있기 때문에 재귀 없이도 댓글을 필터링할 수 있습니다. 예:

SELECT * FROM comment WHERE depth < 5;

Write Performance

깊이 검증은 O(1) 입니다: 부모 레코드만 필요하며, 이는 보통 이미 로드된 상태입니다.

UI Friendly

API 응답에 depth 필드를 노출합니다. 프론트엔드에서는 이 값을 이용해 쉽게 들여쓰기를 적용할 수 있습니다. 예: margin-left: depth * 20px.

Conclusion

단순한 depth 정수 컬럼을 저장함으로써 얻을 수 있는 장점:

  • 즉시 검증 로직 구현.
  • 읽기/쓰기 쿼리 속도 향상.
  • UI 처리 간소화.

삽입 시 재귀 쿼리를 피하고, 대신 비정규화된 depth 컬럼을 활용하세요.

Back to Blog

관련 글

더 보기 »

소프트 스킬의 구성 요소: 6Ts

요약 - Soft skills는 본질적으로 새롭게 나타나는 특성을 가지고 있다. - 구성 요소는 다음 6가지 T로 이루어져 있다: Tools 1. Tool 2. Technique 3. Thought 4. Tenet Actions 5. Training 6...