안녕하세요. 오늘은 mysql에서 rand 함수에 관해 알아보겠습니다. 함수 기능 설명 및 간단한 사용법에 관해 알아보고, 특히 시드 설정 관련하여 여러모로 조사한 부분을 공유해 드리고자 합니다.
그러면 지금부터 한번 살펴보도록 하겠습니다.
RAND 함수
rand 함수는 말 그대로 랜덤한 숫자를 불러오는 함수입니다. 공식 문서 설명을 한번 봅시다.
0부터 1사이의 랜덤한 부동소수점 숫자를 리턴한다고 적혀 있습니다.
직접 실행해 보도록 하겠습니다. 3개의 랜덤한 숫자를 한번 뽑아보았습니다.
0과 1 사이의 서로 다른 숫자 3개가 생성된 것을 확인할 수 있습니다.
위의 공식 문서 설명을 보면 i와 j 사이의 정수 R을 구하는 쿼리도 잘 작성되어 있는데, 이 역시 직접 실행해 보겠습니다.
ORDER BY에도 사용할 수 있는데, 아래와 같이 쿼리를 작성하면 랜덤한 순서로 데이터를 조회할 수 있습니다.
SELECT * FROM tbl_name ORDER BY RAND();
같은 난수를 생성하고 싶다면 아래와 같이 n 위치에 시드값을 설정하시면 됩니다.
SELECT RAND(n);
몇 번을 실행해도 항상 같은 값을 조회하게 됩니다.
RAND 함수 시드값
RAND 함수 시드값 범위
MySQL에서 RAND 함수에 seed 범위가 어디까지 허용되는지에 관해서는 문서에 잘 나타나 있지 않은데요, 정수 N이라고 공식 문서에서는 표현하고 있습니다.
그 외에는 공식 문서 어느 곳을 찾아봐도 명확히 명시되어 있지 않았고, 여러 가지로 조사해 본 결과 stackoverflow에서 관련 자료를 찾을 수 있었습니다.
https://stackoverflow.com/questions/22857902/what-is-the-maximum-seed-value-n-for-mysql-randn
What is the maximum seed value N for mysql RAND(N)
from https://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand ...RAND(N)...If a constant integer argument N is specified, it is used as the seed value,... what is the max...
stackoverflow.com
설명으로는 UNSIGNED BIGINT 타입인 18446744073709551615까지 지원한다고 하는데, 직접 테스트해 보았습니다. (C/C++ 기준 unsigned long long 최댓값)
시드값이 18446744073709551614인 경우는 0.6548542126, 18446744073709551615는 0.905037322입니다. 그런데, 18446744073709551616를 보면, 이전 값과 동일한 것을 확인할 수 있습니다. 거기에 우측 상단 Output을 보면 Truncated incorrect DECIMAL value: '18446744073709551616' 이라며 오류 메시지 역시 출력하고 있어, 제대로 동작하지 않는 것을 확인할 수 있었습니다.
타 함수 문서와 비교
실험을 통해서는 확인했지만, 마음 한구석이 아직 찜찜해서 조금 더 찾아보게 되었습니다. 똑같이 N으로 명시하고 있는 다른 함수들에 관해 살펴보았습니다.
CONV(N, from_base, to_base) 함수의 N은 정수 또는 문자열이며, from_base가 양수일 때, 64비트 unsigned로 동작한다고 합니다.
또한 HEX(N or S) 함수는 string 쪽 문서에 있어서 또 가서 살펴보았는데, 이 역시 longlong(BIGINT)를 지원한다고 합니다.
MOD(N, M) 함수의 경우에는 아예 BIGINT에 대해 safe하다고 명시해 놓았습니다.
공식 문서와 직접 테스트해 본 결과, 그리고 stackoverflow의 설명을 종합해 볼 때, mysql은 기본적으로 정수형 인자 N에 대해 BIGINT 타입을 보장한다고 판단할 수 있을 것 같습니다. 다만, rand 함수만 문서에 명확하게 적혀있지 않은 만큼, 추후 구현이 변경되지는 않는지 유의할 필요가 있어 보입니다.
번외편: 타 DBMS와 비교
찾아보다 보니 다른 데이터베이스는 어떻게 설명이 되어 있을까 조금 궁금해졌습니다. Oracle이나 PostgreSQL의 시드 설정하는 부분 문서도 살펴보았는데, 모두 명확하게 명시되어 있었습니다. MySQL도 문서 부분이 조금 개선되면 좋을 것 같습니다.
참고로 Oracle은 BINARY_INTEGER 타입, PostgreSQL은 double precsion 타입을 사용하고 있습니다.
Mysql rand 함수에 관해 알아보았습니다. 사실 rand 함수를 알아보는 내용보다 시드값 범위에 관해 조사하는 부분이 더 많아진 것 같기도 합니다. 다른 DBMS 시드 값과도 비교해 볼 수 있는 재밌는 시간이었던 것 같습니다.
직접 조사해서 작성하는 글이다 보니 일부 정확하지 않은 정보가 포함되어 있을 수 있습니다.
궁금한 사항이나 잘못된 내용이 있으면 댓글로 알려주세요~
구독과 좋아요, 환영합니다!