티스토리 뷰

사용자 정의 변수 소개

변수의 종류

MySQL의 변수는 누가 생성하는지에 따라 시스템 변수와 사용자 변수로 구분된다.
변수의 적용 범위가 MySQL 전체인지 아니면 커넥션 범위인지에 따라서 글로벌 변수와 세션 변수로 나뉘기도 한다.
또한 동적으로 서버의 중단 없이 변수를 변경할 수 있는지에 따라 동적 변수와 정적 변수로 구분되기도 한다.

사용자 정의 변수는 말그대로 사용자 변수이면서, 해당 커넥션에서만 유효한 세션 변수이고, 언제든지 값을 변경할 수 있기 때문에 동적 변수로 볼 수 있다.

사용자 정의 변수의 사용

하나의 커넥션에서 정의된 사용자 변수는 다른 커넥션과 공유되지 못하고 해당 커넥션에서만 사용할 수 있다.
MySQL의 사용자 변수 이름은 @로 시작한다.

사용자 정의 변수에 할당할 수 있는 값의 타입은 Integer, Decimal, Float, Binary, 문자열 타입이며, 아무런 타입을 할당하지 않는다면 NULL이 기본값으로 정의된다.

값을 할당하기 위해서는 다음과 같이 = 또는 :=를 사용한다.

SET @var := 'User Variable';

또한 다음과 같이 연산 결과를 다시 사용자 변수에 할당할 수도 있다.

// 행 번호를 구할 수 있는 쿼리
SELECT (@rownum := @rownum + 1) AS rownum, col1, col2 FROM sample_tbl LIMIT 5;

사용자 변수 사용 시 주의할 점

사용자 변수를 사용할 때 반드시 기억해야 할 부분은 "절대 동일 SQL 문장에서 변수에 값을 할당하고 동시에 값을 참조하지 말라"는 것이다.
바로 위의 예제처럼 사용하는 것이 그것인데, 이는 MySQL이 이 문장의 결과를 항상 보장하지 않는다는 것을 의미한다.
다만 하나의 버전 안에서는 같은 방식으로 처리되므로 같은 버전 내에서는 일관된 결과로 사용할 수 있다.
그래서 사용자 변수는 주로 중요 애플리케이션 로직 보다는 일회성의 대량 작업에 사용할 경우가 많다.

사용자 정의 변수의 사용 시 주의할 점은 다음과 같다.

  • 5.0버전부터는 변수명의 대소문자를 구분하지 않는다.
  • 해당 쿼리는 쿼리 캐시 기능을 사용할 수 없다.
  • 초기화되지 않은 변수는 문자열 타입의 NULL값을 가진다.
  • 사용자 정의 변수의 연산 순서는 정해져 있지 않다. (MySQL에서 보장하지 않는다.)
  • MySQL 버전에 따른 작동 방식, 순서에 차이가 있기 때문에 여러 버전에 걸쳐서 사용할 때는 주의해야 한다.

사용자 변수의 사용

기본 활용

사용자 변수는 하나의 커넥션에서는 공유된다.
따라서 커넥션 풀을 사용하는 일반적인 웹 프로그램에서 변수를 사용할 때마다 초기화하지 않는다면 각 코드가 상호 영향을 끼칠 수 있다.

따라서 보통 SQL 문장 자체에서 사용자 정의 변수를 초기화하는 방법을 사용한다.

SELECT (@rownum := @rownum + 1) AS rownum, col1, col2 
FROM sample_tbl, (SELECT @rownum := 0) x
LIMIT 5;

"SELECT @rownum := 0"은 SET 명령과 동일한 역할을 수행한다.

SQL 문장에서 FROM 절은 쿼리 실행 시 단 1번만 참조되기 때문에 사용자 정의 변수를 초기화하기에 아주 적절한 위치이다.
다만 ORDER BY가 사용된 JOIN UPDATE나 JOIN DELETE에서는 사용할 수 없다.

해당 초기화 서브쿼리 뒤의 "x"는 서브쿼리의 별칭이다. (필수)

"(@rownum := @rownum + 1)" 과 같이 대입 연산자를 기준으로 좌측에 있는 값이 반환되는 형태의 표현식을 "L-value 표현식"이라고 한다.


참고

위 내용은 이성욱님의 Real MySQL (위키북스) 에서 일부 내용을 간단하게 정리한 것입니다.
세부적인 내용은 책을 직접 구입하셔서 읽어보시는 것을 추천드립니다.

'Database > Real MySQL' 카테고리의 다른 글

[Real MySQL] 13. 프로그램 연동  (0) 2020.09.08
[Real MySQL] 12. 쿼리 종류별 잠금  (0) 2020.09.07
[Real MySQL] 9. 사용자 정의 변수  (0) 2020.09.01
[Real MySQL] 10. 파티션  (0) 2020.08.22
[Real MySQL] 4. 트랜잭션과 잠금  (0) 2020.08.17
[Real MySQL] 3. 아키텍처  (0) 2020.08.10