0Pricing
SQL Interview Prep · 강의

무한 재귀 방지하기

순환 감지, 깊이 제한, 면접관이 확인하는 재귀 보호 장치를 알아봅니다.

무한 재귀 방지하기은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

질문에 숨은 의도

재귀 CTE를 작성한 뒤, 날카로운 면접관은 다음과 같이 질문합니다. "데이터에 순환이 있으면 어떻게 됩니까?" 이 질문은 재귀가 영원히 실행될 수 있다는 점과, 이를 방지하는 방법을 알고 있는지 확인합니다.

순환은 계층이 자기 자신으로 되돌아오는 경우입니다. A는 B에게 보고하고 B는 A에게 보고합니다. 단순한 재귀 멤버는 두 행 사이를 무한히 오가게 됩니다.

순환이 만들어지는 방식

트리는 원래 비순환이어야 하지만 실제 데이터는 복잡합니다. 잘못된 변경으로 직원이 자신의 직접 또는 간접 관리자가 될 수 있습니다. "사용자가 다른 사용자를 따르는 관계"와 같은 그래프는 본질적으로 순환적입니다.

재귀 멤버가 이미 방문한 노드를 다시 만나면 해당 노드를 다시 생성하고, 그러면 그 자식들이 다시 처리되어 반복이 끝나지 않습니다. 재귀는 어떤 단계가 행을 반환하지 않을 때만 멈추며, 순환이 있으면 항상 행을 반환하게 됩니다.

보호 장치 1: 깊이 제한

가장 간단한 안전 장치는 재귀 멤버에 상한을 둔 깊이 카운터를 추가하는 것입니다. 순환이 있더라도 재귀가 해당 한도에서 멈춥니다.

이는 정상적인 깊은 트리까지 제한하는 거친 방법이지만, 빠르게 적용할 수 있고 면접에서 설명하기도 쉽습니다.

WITH RECURSIVE org AS (
    SELECT id, name, manager_id, 1 AS depth
    FROM employees WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id, o.depth + 1
    FROM employees e JOIN org o ON e.manager_id = o.id
    WHERE o.depth < 50
)
SELECT * FROM org;

보호 장치 2: 방문 경로

정밀한 보호 장치는 방문한 노드의 경로를 추적하고, 경로에 이미 있는 노드로 다시 들어가지 않도록 합니다. ID를 문자열이나 배열에 누적하고 재귀하기 전에 포함 여부를 확인합니다.

이 방법은 정상적인 트리에서는 깊이를 제한하지 않으면서 순환만 정확하게 중단합니다.

WITH RECURSIVE org AS (
    SELECT id, name, manager_id,
           CAST(',' || id || ',' AS VARCHAR(2000)) AS path
    FROM employees WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id,
           o.path || e.id || ','
    FROM employees e JOIN org o ON e.manager_id = o.id
    WHERE o.path NOT LIKE '%,' || e.id || ',%'
)
SELECT id, name, path FROM org;

경로 확인이 작동하는 이유

조건식 path NOT LIKE '%,' || e.id || ',%'은 "자식 ID가 경로에 이미 없을 때만 이 간선을 따른다"는 뜻입니다. 쉼표가 구분자 역할을 하므로 ID 1이 ID 15의 일부와 잘못 일치하지 않습니다.

순환으로 인해 노드를 다시 방문하려 하면 WHERE가 해당 행을 제외하고, 재귀 멤버는 결국 아무것도 반환하지 않으므로 재귀가 정상적으로 종료됩니다.

보호 장치 3: 기본 제공 CYCLE 절

최신 PostgreSQL(14 이상)과 SQL 표준은 경로 확인을 자동화하고 순환을 표시해 주는 기본 제공 CYCLE 절을 제공합니다. 엔진에서 지원한다면 가장 깔끔한 답변입니다.

WITH RECURSIVE org AS (
    SELECT id, name, manager_id FROM employees WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id
    FROM employees e JOIN org o ON e.manager_id = o.id
)
CYCLE id SET is_cycle USING cycle_path
SELECT id, name, is_cycle FROM org;

SQL 서버의 MAXRECURSION

SQL 서버는 기본적으로 재귀 단계를 100회로 제한합니다. 순환이나 깊은 트리가 이 한도를 넘으면 쿼리가 무한히 반복되는 대신 오류가 발생합니다 — 일종의 암묵적인 안전 장치입니다.

OPTION (MAXRECURSION n)을 사용하면 한도를 높이거나 제거할 수 있으며, 0은 무제한을 뜻합니다. 하지만 경로 보호 장치 없이 한도를 제거하면 순환 데이터에서 무한 반복 위험이 다시 생깁니다.

-- Cap recursion at 200 levels in SQL Server
SELECT * FROM org
OPTION (MAXRECURSION 200);

순환 감지와 방지

면접관은 다음 두 가지 목표를 구분할 수 있습니다:

  • 방지 — 순환하는 간선을 조용히 건너뛰어 쿼리를 완료합니다(경로 확인 WHERE).
  • 감지 및 보고 — 어떤 행이 순환의 일부인지 드러내 데이터 팀이 잘못된 데이터를 수정할 수 있게 합니다(CYCLE 절의 is_cycle 플래그).

두 방법을 모두 알고 언제 각각 적절한지 판단하는 것이 시니어 수준의 차이입니다.

성능 고려 사항

순환이 없어도 재귀는 비용이 클 수 있습니다. 면접에서 좋은 평가를 받는 요점은 다음과 같습니다:

  • 각 반복의 조인이 빠르게 수행되도록 조인 열(예: manager_id)에 인덱스를 만듭니다.
  • 앵커에서 일찍 필터링하여 전체 테이블이 아니라 필요한 하위 트리만 시작점으로 지정합니다.
  • SELECT *를 피하고, 재귀에 필요한 열과 depth/path만 전달합니다.

안전한 템플릿

압박 속에서도 재현할 수 있는 템플릿으로 보호 장치를 결합해 보세요. 깊이 열은 최후의 방어선으로 사용하고, 경로 확인은 정밀한 보호 장치로 사용합니다. 깨끗한 데이터에는 하나가 지나칠 수 있더라도 두 가지를 모두 보여 주면 엄밀한 접근임을 드러낼 수 있습니다.

WITH RECURSIVE walk AS (
    SELECT id, parent_id, 1 AS depth,
           CAST(',' || id || ',' AS VARCHAR(4000)) AS path
    FROM nodes WHERE parent_id IS NULL
    UNION ALL
    SELECT n.id, n.parent_id, w.depth + 1,
           w.path || n.id || ','
    FROM nodes n JOIN walk w ON n.parent_id = w.id
    WHERE w.depth < 100
      AND w.path NOT LIKE '%,' || n.id || ',%'
)
SELECT id, depth FROM walk;

흔한 면접 실수

마지막으로 피해야 할 함정은 다음과 같습니다:

  • 다른 보호 장치 없이 SQL 서버에서 MAXRECURSION을 제거하는 것 — 무한 반복 위험이 다시 생깁니다.
  • 경로 문자열 열을 너무 짧게 선언하는 것 — 잘림이 발생해 보호 장치가 조용히 무력화됩니다.
  • 쉼표 구분자 없이 ID를 일치시키는 것 — ID 1이 ID 21 안에 있다고 잘못 일치합니다.
  • 데이터가 당연히 비순환일 것이라고 가정하는 것 — 항상 확인해야 합니다.

간단 확인

정상적인 깊이를 제한하지 않으면서 순환을 정확하게 중단하는 보호 장치를 고르세요.

복습

모든 재귀 CTE 답변은 안전성을 다뤄야 합니다:

  • 순환이 있으면 재귀 멤버가 빈 결과를 반환하지 않으므로 재귀가 멈추지 않습니다.
  • 깊이 상한 = 빠른 최후 방어선, 방문 경로 확인 = 정확한 순환 방지, CYCLE 절 = 최신 엔진에서 제공하는 기본 감지 기능입니다.
  • SQL 서버의 MAXRECURSION 100은 암묵적인 안전 밸브이므로, 다른 보호 장치 없이 제거하지 마세요.
  • 성능을 위해 조인 열에 인덱스를 만들고 시작 범위를 좁게 지정합니다.

이제 재귀 CTE를 처음부터 끝까지 작성하고, 순회하고, 생성하고, 안전하게 보호할 수 있습니다.

자주 묻는 질문

“무한 재귀 방지하기” 강의는 무료인가요?

네 — “무한 재귀 방지하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

“무한 재귀 방지하기”에서 뭘 배우나요?

순환 감지, 깊이 제한, 면접관이 확인하는 재귀 보호 장치를 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

SQL Interview Prep을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 SQL Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“무한 재귀 방지하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 SQL Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 SQL Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 앵커 및 재귀 구성원
  2. 조직도 순회하기
  3. 숫자 및 날짜 계열 생성하기
  4. 무한 재귀 방지하기
← SQL Interview Prep(으)로 돌아가기