ORDER BY NEWID에 대해

Wikipedia에서 발췌 번역

보통 GUID는 마이크로소프트가 구현한 Universally Unique Identifier (UUID) 표준을 일컫는다. 하지만 오라클 데이터베이스, MySQL, dBase 같은 다수의 시스템도 GUID란 용어를 쓴다.

알고리즘

V1 GUID는 MAC 주소와 시간이 포함되는데 세번째 숫자 집단의 첫 숫자가 "1"이다. 예를 들면 이렇다. {2f1e4fc0-81fd-11da-9156-00036a0f876a}.

V4 GUID는 좀더 최신의 알고리즘을 쓰는데 의사 난수(Peudo-random number)이다. V4 GUID는 똑같은 위치에 4가 들어간다. {38a52be4-9352-453e-af97-5c3b448652f0}. WinAPI GUID 생성기를 분석해보니, V4 GUID가 의사 난수인 탓에 초기 상태를 알면 UuidCreate 함수가 앞으로 반환할 250000 개의 GUID를 예측할 수 있음이 밝혀졌다. 그러므로 암호화시 GUID를 난수 키로 써선 안 된다.

NEWID()를 이용한 방법에 대해

우선, MSSQL에서 진짜 랜덤 숫자를 얻는 방법에 잘못된 부분부터 밝혀야겠군요. 16비트가 아닌 16바이트인데 한 대목은 16비트 다른 대목은 16바이트라고 쓴 것을 보아 단순한 실수일 겁니다. 둘째, NEWID()는 서버의 네트워크 카드의 MAC 주소 + 애플리케이션 또는 쿼리를 돌리는 컴퓨터의 시계로부터 얻은 유일한 값의 조합이다.이란 말이 틀렸습니다. 확인해보니 MSSQL의 NEWID() 함수는 V1 GUID가 아닌 V4 GUID를 반환합니다.

방준영님의 지적에 대해

그런데 제목에 약간 어폐가 있네요. NEWID()로부터 얻은 GUID 값은 예측가능한 수 여러 개를 조합한 것이기 때문에 랜덤값이 아닙니다(무작위 != 유일). 왜 GUID를 랜덤 키로 쓰면 안되는지는 http://en.wikipedia.org/wiki/Guid 에 나와 있습니다.

위키피디아로 공부해보니 전부 맞는 내용이더군요. 제목에도 문제가 있었습니다. MSSQL에서 진짜 랜덤 숫자를 얻는 방법에서 MSSQL에서 랜덤 레코드를 얻는 방법이라 고쳤습니다. 진짜 랜덤이란 게 정확한 표현이 아니었고, 숫자 아닌 레코드를 SELECT하는 방법을 다룬 글인데 오해의 소지가 많더군요.

일단 의사 난수이고 뒤이어 나올 값을 예측할 수 있으니 암호화엔 못 쓰겠지만, 데이터베이스에서 레코드를 무작위로 가져오는 용도론 충분하겠습니다. OLTP(Online Transaction Processing) 시스템에선 데이터가 자주 업데이트 되니 사실상 무작위적인 레코드 집합이 나오겠네요.

어쨌거나 ORDER BY RAND()로는 무작위 레코드 추출이 힘들기 때문에 NEWID()를 쓰는 게 최선인 듯 합니다.

의문점

ORDER BY NEWID()를 레코드를 무작위로 뽑아내는 표준 정도로 받아들이는 분위기인데, 이 방법의 출처가 어디인지, 그리고 그 작동기작은 무엇인지 알아내기 힘들드네요. ORDER BY 뒤엔 칼럼의 이름이나 칼럼의 인덱스(1부터 시작하는)가 들어가는데, 어떻게 NEWID()RAND()ORDER BY에 쓰일 수 있는지 모르겠군요.

-- RAND() 대신 0과 1 사이의 float 값 넣어보기
SELECT TOP 10 *
FROM SOMETABLE
ORDER BY CAST(0.1 AS FLOAT)

-- NEWID() 대신 상수 값을 넣어보기
SELECT TOP 10 *
FROM SOMETABLE
ORDER BY '6F9619FF-8B86-D011-B42D-00C04FC964FF'

SELECT TOP 10 *
FROM SOMETABLE
ORDER BY CAST ('6F9619FF-8B86-D011-B42D-00C04FC964FF' AS uniqueidentifier)

위와 같은 쿼리를 실행시키면 이런 오류 메시지가 나옵니다.

메시지 408, 수준 16, 상태 1, 줄 1
ORDER BY 목록, 위치 1에 상수 식이 있습니다.

이 기능에 대한 공식 문서를 찾아야 의문이 풀릴 듯 한데 답답하군요.

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu