공지. 이 글은 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()))을 쓰면 된다.
Pingback: KAISTIZEN
“…16비트 바이너리…” -> 128비트가 맞겠죠.
그런데 제목에 약간 어폐가 있네요. NEWID()로부터 얻은 GUID 값은 예측가능한 수 여러 개를 조합한 것이기 때문에 랜덤값이 아닙니다(무작위 != 유일). 왜 GUID를 랜덤 키로 쓰면 안되는지는 http://en.wikipedia.org/wiki/Guid 에 나와 있습니다.
별로 생각 안 하고 원문을 그대로 옮겨서 조사를 해보고 답변해야겠네요. 흠……
원문을 봤더니 저자가 착각을 해서 “16 byte”라고 써야 할 부분에 “16 bit”라고 써놨네요. 그 아랫줄에서는 “16-byte”라고 제대로 되어 있습니다.
우선 16바이트로 고쳐놨습니다. 그리고 이 랜덤 이야기는 조금 더 다룰 생각인데 집 컴퓨터엔 개발 도구가 많지 않아 힘들고 내일 일찍 출근해서 실험을 해봐야 알겠네요. ^^