공지. 이 글은 How to get a really random number with MSSQL을 번역한 것입니다.
-
rand()란 무작위 함수는 0과 1을 포함하여 0과 1 사이의 float 값을 반환한다.
-
온라인 설명서에 따르면 "동일한 초기값으로 RAND()를 반복 호출하면 동일한 결과를 반환한다”라는 문제가 있다. 헉!
-
온라인 설명서에 따르면 이렇단다. [강조는 내가 한 것이다]
seed를 지정하지 않으면 Microsoft SQL Server 2005 데이터베이스 엔진은 임의로 초기값을 할당합니다. 지정된 초기값에 대해 반환된 결과는 항상 동일합니다.
적용 대상
- Microsoft SQL Server 2000
- Microsoft SQL Server 2005
- Microsoft SQL Server 2008
테스트 시 사용한 데이터
USE sql911; go SELECT counter,emp_short,trans_date,debit,credit FROM trans02 WHERE counter IS not null; go
counter emp_short trans_date debit credit ----------- --------- ----------------------- --------------------- --------------------- 10 000190 2007-06-01 00:00:00.000 NULL 125.00 20 000110 2007-06-01 00:00:00.000 NULL 100.00 30 000190 2007-06-02 00:00:00.000 25.00 NULL 40 000030 2007-07-15 00:00:00.000 357.00 NULL 50 000030 2007-07-16 00:00:00.000 NULL 22.00 60 000030 2007-07-18 00:00:00.000 NULL 41.00 70 000030 2007-07-20 00:00:00.000 NULL 29.50 80 000110 2007-07-20 00:00:00.000 42.00 NULL 90 000110 2007-07-22 00:00:00.000 66.00 NULL 100 000110 2007-07-23 00:00:00.000 77.00 NULL 110 000010 2007-07-23 00:00:00.000 11.00 NULL 120 000010 2007-07-24 00:00:00.000 22.56 NULL 130 000010 2007-07-25 00:00:00.000 33.69 NULL (13 row(s) affected)
무작위 숫자
SELECT newid() AS 'New id', RAND() AS 'Random not working', CHECKSUM(newid()) AS 'Checksum', counter,emp_short,trans_date,debit,credit FROM trans02 WHERE counter IS not null ORDER BY 3;
New id Random not working Checksum counter emp_short ------------------------------------ ---------------------- ----------- ----------- --------- F137931B-664F-4CB7-B597-03105FD9E96A 0.838972959717442 -1608727751 20 000110 3A934F70-5046-4D3D-9F7C-797EAB13B913 0.838972959717442 -1344834565 120 000010 41E3CB22-A949-4908-8BC2-B41B5B5BF577 0.838972959717442 -1134949697 100 000110 45BCFA1F-BD8F-4592-99D6-B78F306A7504 0.838972959717442 -774042085 60 000030 4A976789-B334-4955-A70F-0D85D9C4B2D6 0.838972959717442 -251363326 90 000110 E5AC2F6A-2C8E-4143-B3B9-A21E8B9D4E7C 0.838972959717442 -247038803 130 000010 0F58C42C-7C60-4099-A172-D5C88259AE3D 0.838972959717442 277019267 80 000110 5F88145E-A98C-43E0-BF45-100CBFC736AF 0.838972959717442 389707540 30 000190 F65079CC-7EA0-414E-823B-656E0ED5332B 0.838972959717442 477599931 110 000010 E6C128E8-B547-4D31-BD13-BE90C77604A6 0.838972959717442 876100622 70 000030 7490BBA7-2F6D-4E8E-A399-E1369B38F265 0.838972959717442 1578680847 10 000190 65D886A7-5837-4660-AE25-8AABA9DB1975 0.838972959717442 1693370092 40 000030 A992E547-E740-443C-85C0-679AB2E2A34B 0.838972959717442 2061729487 50 000030 (13 row(s) affected)
NEWID()
-
NEWID()는 진정으로 유일한 16바이트 바이너리 값을 제공한다. 거의 무작위에 가깝다.
-
NEWID()는 16바이트 바이너리 값이다. 이 값은 유일하며 세상 어느 컴퓨터도 똑같은 값을 만들지 않는다.
-
NEWID()는 서버의 네트워크 카드의 MAC 주소 + 애플리케이션 또는 쿼리를 돌리는 컴퓨터의 시계로부터 얻은 유일한 값의 조합이다.
-
NEWID()는 유일한 값을 얻고자 할 때 매우 유용하다.
-
알파벳과 숫자로 이뤄진 문자열이 아닌 숫자를 셀 때 쓰는 정수가 필요하다면,
checksum(newid())
와abs(checksum(newid()))을 쓰면 된다.
Author Details
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
“…16비트 바이너리…” -> 128비트가 맞겠죠.
그런데 제목에 약간 어폐가 있네요. NEWID()로부터 얻은 GUID 값은 예측가능한 수 여러 개를 조합한 것이기 때문에 랜덤값이 아닙니다(무작위 != 유일). 왜 GUID를 랜덤 키로 쓰면 안되는지는 http://en.wikipedia.org/wiki/Guid 에 나와 있습니다.
별로 생각 안 하고 원문을 그대로 옮겨서 조사를 해보고 답변해야겠네요. 흠……
원문을 봤더니 저자가 착각을 해서 “16 byte”라고 써야 할 부분에 “16 bit”라고 써놨네요. 그 아랫줄에서는 “16-byte”라고 제대로 되어 있습니다.
우선 16바이트로 고쳐놨습니다. 그리고 이 랜덤 이야기는 조금 더 다룰 생각인데 집 컴퓨터엔 개발 도구가 많지 않아 힘들고 내일 일찍 출근해서 실험을 해봐야 알겠네요. ^^
ORDER BY NEWID에 대해
Wikipedia에서 발췌 번역 보통 GUID는 마이크로소프트가 구현한 Universally Unique Identifier (UUID) 표준을 일컫는다. 하지만 오라클 데이터베이스, MySQL, dBase 같은 다수의 시스템도 GUID란 용어를 쓴다. 기본 구조 GUID는 16바이트(128비트) 짜리 숫자다. 주로 사용하는 데이터 타입의 구조는 다음과 같다. Bits Bytes Description 32 4 Data1 16 2 Data2 16 2 Data3 64 8 Data4 알고리즘 V1 GUID는 MAC 주소와 시간이 포함되는데……