NO_UNSIGNED_SUBTRACTION SQL 모드란 무엇인가?
MySQL에서 SQL 엄격 모드(strict mode)가 활성화된 상태에서는, 정수 값 간의 뺄셈 연산에서 피연산자 중 하나라도 UNSIGNED(부호 없음) 타입이면 그 결과는 기본적으로 부호 없는 값으로 처리됩니다. 따라서 뺄셈 결과가 음수가 되면 MySQL은 오류를 반환합니다. 다음 예제를 통해 직접 확인해 보겠습니다.
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> Select CAST(0 AS UNSIGNED) -1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
위 쿼리 실행 후 발생한 오류 메시지는 숫자 산술 표현식에서 오버플로(overflow)가 발생했음을 보여줍니다. 즉, 부호 없는 값에서 더 작은 수를 빼려고 했기 때문에 결과를 UNSIGNED 범위 안에 표현할 수 없어 에러가 발생한 것입니다.
NO_UNSIGNED_SUBTRACTION 모드로 오버플로 오류 해결하기
이러한 문제는 NO_UNSIGNED_SUBTRACTION SQL 모드를 활성화하면 간단히 해결할 수 있습니다. 이 모드를 설정하면 UNSIGNED 값 간의 뺄셈 결과가 음수가 되더라도 오류 대신 정상적인 음수 값을 반환합니다.
mysql> Set sql_mode = 'NO_UNSIGNED_SUBTRACTION';
Query OK, 0 rows affected (0.00 sec)
mysql> Select CAST(0 AS UNSIGNED) -1;
+------------------------+
| CAST(0 AS UNSIGNED) -1 |
+------------------------+
| -1 |
+------------------------+
1 row in set (0.00 sec)
모드 활성화 후에는 동일한 쿼리가 오류 대신 -1이라는 결과를 반환하는 것을 확인할 수 있습니다.
정리
- 기본 엄격 모드에서는 UNSIGNED 값의 뺄셈 결과가 음수가 되면 오류(ERROR 1690)가 발생합니다.
- NO_UNSIGNED_SUBTRACTION 모드를 사용하면 음수 결과도 허용되어 오버플로 오류를 방지할 수 있습니다.
- 다만, 이 모드를 남용하면 의도하지 않은 음수 값이 저장될 수 있으므로 데이터 특성에 맞게 신중하게 적용하는 것이 좋습니다.