Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL 저장 프로시저로 팩토리얼(계승) 계산하기 – 재귀 호출 완벽 가이드

개요

팩토리얼(계승, Factorial)은 1부터 N까지의 모든 양의 정수를 곱한 값으로, 수학과 프로그래밍에서 자주 등장하는 개념입니다. MySQL에서는 저장 프로시저(Stored Procedure)의 재귀 호출 기능을 활용하면 별도의 애플리케이션 코드 없이 데이터베이스 내부에서 팩토리얼을 계산할 수 있습니다.

이 글에서는 두 개의 저장 프로시저를 조합해 팩토리얼을 구하는 방법을 단계별로 살펴보겠습니다. 하나는 실제 재귀 연산을 수행하는 프로시저이고, 다른 하나는 이를 감싸서 결과를 출력하는 진입점 역할을 합니다.

1. 재귀 깊이 설정하기

저장 프로시저에서 재귀 호출을 사용하려면 먼저 최대 재귀 깊이(max_sp_recursion_depth)를 충분히 크게 설정해야 합니다. 전역 변수와 세션 변수 모두에 값을 지정하는 것이 안전합니다.

SET @@GLOBAL.max_sp_recursion_depth = 255;
SET @@session.max_sp_recursion_depth = 255;

2. 메인 프로시저 생성

사용자가 직접 호출할 메인 프로시저를 먼저 만듭니다. 이 프로시저는 재귀 깊이를 설정한 뒤 실제 계산을 담당하는 재귀 프로시저를 호출하고, 세션 변수 @factorial에 담긴 결과를 SELECT 문으로 출력합니다.

mysql> DELIMITER //
mysql> CREATE PROCEDURE get_factorial(IN N INT)
    -> BEGIN
    ->     SET @@GLOBAL.max_sp_recursion_depth = 255;
    ->     SET @@session.max_sp_recursion_depth = 255;
    ->
    ->     CALL factorial_recursive (N, @factorial);
    ->
    ->     SELECT @factorial;
    -> END //
Query OK, 0 rows affected (0.00 sec)

3. 재귀 프로시저 생성

다음으로 실제 팩토리얼 연산을 수행하는 재귀 프로시저를 작성합니다. N이 1이면 결과값을 1로 설정하고, 그렇지 않으면 N-1로 자기 자신을 재귀 호출한 뒤 현재 값 N을 곱하는 방식으로 동작합니다.

mysql> DELIMITER //
mysql> CREATE PROCEDURE factorial_recursive(IN N INT,OUT factorial INT)
    -> BEGIN
    ->     IF N = 1 THEN
    ->         SET factorial := 1;
    ->     ELSE
    ->         CALL factorial_recursive (N-1, factorial);
    ->         SET factorial := N * factorial;
    ->     END IF;
    -> END //
Query OK, 0 rows affected (0.00 sec)

프로시저 생성이 끝나면 구분자(Delimiter)를 반드시 원래대로 되돌려 놓습니다.

mysql> DELIMITER ;

4. 실행 및 결과 확인

이제 프로시저를 호출해 팩토리얼을 계산해 보겠습니다.

mysql> Call get_factorial(10);
+--------------+
| @factorial   |
+--------------+
|      3628800 |
+--------------+
1 row in set (0.11 sec)

mysql> Call get_factorial(5);
+-------------+
| @factorial  |
+-------------+
|         120 |
+-------------+
1 row in set (0.00 sec)

10! = 3,628,800, 5! = 120이 정상적으로 출력되는 것을 확인할 수 있습니다.

동작 원리 정리

  • get_factorial(N) : 외부에서 호출하는 진입점 역할. 재귀 깊이를 설정하고 재귀 프로시저를 호출한 뒤 결과를 SELECT로 반환합니다.
  • factorial_recursive(N, OUT factorial) : 실제 재귀 로직을 담당. N=1이면 1을 반환하고, 그 외에는 N-1에 대한 재귀 호출 결과에 N을 곱합니다.
  • @factorial : 세션 사용자 변수로, OUT 파라미터를 통해 재귀 프로시저와 메인 프로시저 사이에서 결과를 전달합니다.

주의 사항

재귀 호출을 사용할 때는 max_sp_recursion_depth 값을 적절히 설정해야 합니다. 기본값이 0(재귀 비활성화) 또는 매우 낮은 값으로 되어 있으면 재귀 프로시저가 실행되지 않을 수 있습니다. 또한 INT 타입은 표현 범위가 제한적이므로, N이 커지면 오버플로로 인해 잘못된 결과가 반환될 수 있습니다. 큰 수의 팩토리얼이 필요하다면 BIGINT 타입 사용을 검토하거나, 애플리케이션 계층에서 처리하는 것이 바람직합니다.