PostgreSQL을 사용하여 세션 확인에 사용할 임의의 문자열을 만들고 싶습니다. 를 사용하여 난수를 얻을 수 있다는 것을 알고 SELECT random()
있으므로을 시도 SELECT md5(random())
했지만 작동하지 않습니다. 어떻게 할 수 있습니까?
답변
이 간단한 해결책을 제안합니다.
이것은 주어진 길이의 임의의 문자열을 반환하는 아주 간단한 함수입니다.
Create or replace function random_string(length integer) returns text as
$$
declare
chars text[] := '{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}';
result text := '';
i integer := 0;
begin
if length < 0 then
raise exception 'Given length cannot be less than 0';
end if;
for i in 1..length loop
result := result || chars[1+random()*(array_length(chars, 1)-1)];
end loop;
return result;
end;
$$ language plpgsql;
그리고 사용법 :
select random_string(15);
출력 예 :
select random_string(15) from generate_series(1,15);
random_string
-----------------
5emZKMYUB9C2vT6
3i4JfnKraWduR0J
R5xEfIZEllNynJR
tMAxfql0iMWMIxM
aPSYd7pDLcyibl2
3fPDd54P5llb84Z
VeywDb53oQfn9GZ
BJGaXtfaIkN4NV8
w1mvxzX33NTiBby
knI1Opt4QDonHCJ
P9KC5IBcLE0owBQ
vvEEwc4qfV4VJLg
ckpwwuG8YbMYQJi
rFf6TchXTO3XsLs
axdQvaLBitm6SDP
(15 rows)
답변
다음과 같이 초기 시도를 수정할 수 있습니다.
SELECT md5(random()::text);
다른 제안보다 훨씬 간단합니다. 🙂
답변
Marcin의 솔루션을 기반으로이 작업을 수행하여 임의의 알파벳을 사용할 수 있습니다 (이 경우 62 개의 ASCII 영숫자 문자).
SELECT array_to_string(array
(
select substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', trunc(random() * 62)::integer + 1, 1)
FROM generate_series(1, 12)), '');
답변
UUID에서 128 비트를 무작위로 얻을 수 있습니다. 이것은 최신 PostgreSQL에서 작업을 수행하는 방법입니다.
CREATE EXTENSION pgcrypto;
SELECT gen_random_uuid();
gen_random_uuid
--------------------------------------
202ed325-b8b1-477f-8494-02475973a28f
수 있음 도 UUID에 문서를 읽을 가치
데이터 유형 uuid는 RFC 4122, ISO / IEC 9834-8 : 2005 및 관련 표준에 정의 된 대로 UUID (Universally Unique Identifier)를 저장 합니다. (일부 시스템에서는이 데이터 유형을 전역 고유 식별자 또는 GUID라고합니다.)이 식별자는 다른 사람이 동일한 식별자를 생성 할 가능성이 거의 없도록 선택한 알고리즘에 의해 생성되는 128 비트 수량 입니다. 동일한 알고리즘을 사용하여 알려진 우주에서. 따라서 분산 시스템의 경우 이러한 식별자는 단일 데이터베이스 내에서만 고유 한 시퀀스 생성기보다 더 나은 고유성을 보장합니다.
UUID와의 충돌은 얼마나 드물거나 추측 할 수 있습니까? 무작위라고 가정하면
단일 복제 ( “충돌”)의 10 억분의 1의 기회를 가지려면 약 100 조 개의 버전 4 UUID를 생성해야합니다. 한 번의 충돌 가능성은 261 개의 UUID (2.3 x 10 ^ 18 또는 2.3 quintillion)가 생성 된 후에 만 50 %로 증가합니다. 이 숫자를 데이터베이스와 연결하고 버전 4 UUID 충돌 가능성이 무시할 수 있는지 여부를 고려할 때, UUID 충돌을 포함 할 확률이 50 % 인 2.3 quintillion 버전 4 UUID가 포함 된 파일을 고려하십시오. 다른 데이터 나 오버 헤드가 없다고 가정하면 크기가 36 엑사 바이트가되며, 현재 존재하는 가장 큰 데이터베이스 (약 페타 바이트)보다 수천 배 더 큽니다. 초당 10 억 UUID가 생성되는 속도로 파일에 대한 UUID를 생성하는 데 73 년이 걸립니다. 또한 약 3 개가 필요합니다. 6 백만 개의 10 테라 바이트 하드 드라이브 또는 테이프 카트리지로 백업이나 중복성이 없다고 가정합니다. 초당 1 기가비트의 일반적인 “디스크 대 버퍼”전송 속도로 파일을 읽으려면 단일 프로세서에 3000 년 이상이 필요합니다. 드라이브의 복구 할 수없는 읽기 오류율은 읽기 1018 비트 당 1 비트이고 파일에는 약 1020 비트가 포함되어 있기 때문에 파일을 끝에서 끝까지 한 번 읽는 것만으로도 적어도 약 100 배 더 많은 오류가 발생합니다. 중복보다 UUID를 읽습니다. 스토리지, 네트워크, 전원 및 기타 하드웨어 및 소프트웨어 오류는 의심 할 여지없이 UUID 복제 문제보다 수천 배 더 자주 발생합니다. 초당 1 기가비트의 전송 속도는 단일 프로세서에 3000 년 이상이 필요합니다. 드라이브의 복구 할 수없는 읽기 오류율은 읽기 1018 비트 당 1 비트이고 파일에는 약 1020 비트가 포함되어 있기 때문에 파일을 끝에서 끝까지 한 번 읽는 것만으로도 적어도 약 100 배 더 많은 오류가 발생합니다. 중복보다 UUID를 읽습니다. 스토리지, 네트워크, 전원 및 기타 하드웨어 및 소프트웨어 오류는 의심 할 여지없이 UUID 복제 문제보다 수천 배 더 자주 발생합니다. 초당 1 기가비트의 전송 속도는 단일 프로세서에 3000 년 이상이 필요합니다. 드라이브의 복구 할 수없는 읽기 오류율은 읽기 1018 비트 당 1 비트이고 파일에는 약 1020 비트가 포함되어 있기 때문에 파일을 끝에서 끝까지 한 번 읽는 것만으로도 적어도 약 100 배 더 많은 오류가 발생합니다. 중복보다 UUID를 읽습니다. 스토리지, 네트워크, 전원 및 기타 하드웨어 및 소프트웨어 오류는 의심 할 여지없이 UUID 복제 문제보다 수천 배 더 자주 발생합니다.
출처 : wikipedia
요약해서 말하자면,
- UUID가 표준화되었습니다.
gen_random_uuid()
128 비트 (2 ** 128 개 조합)에 저장된 128 비트 랜덤입니다. 0- 폐기물.random()
PostgreSQL에서는 52 비트 만 무작위로 생성됩니다 (2 ** 52 조합).md5()
UUID로 저장되는 것은 128 비트이지만 입력만큼만 임의적 일 수 있습니다 ( 사용하는 경우 52 비트random()
).md5()
텍스트로 저장되는 것은 288 비트이지만 입력만큼만 임의적 일 수 있습니다 ( 사용하는 경우 52 비트random()
)-UUID 크기의 두 배와 임의성의 일부 이상)md5()
해시로 최적화되어 효과적으로 많은 작업을 수행하지 않습니다.- UUID는 저장소에 매우 효율적입니다. PostgreSQL은 정확히 128 비트 유형을 제공합니다. 달리
text
와varchar
등, A와 저장되는varlena
문자열의 길이의 오버 헤드 갖는다. - PostgreSQL 멋진 UUID에는 기본 연산자, 캐스팅 및 기능이 함께 제공됩니다.
답변
나는 최근에 PostgreSQL을 가지고 놀았고 pl / pgsql이 아닌 내장 PostgreSQL 메서드 만 사용하여 조금 더 나은 솔루션을 찾은 것 같습니다. 유일한 제한은 현재 UPCASE 문자열, 숫자 또는 소문자 문자열 만 생성한다는 것입니다.
template1=> SELECT array_to_string(ARRAY(SELECT chr((65 + round(random() * 25)) :: integer) FROM generate_series(1,12)), '');
array_to_string
-----------------
TFBEGODDVTDM
template1=> SELECT array_to_string(ARRAY(SELECT chr((48 + round(random() * 9)) :: integer) FROM generate_series(1,12)), '');
array_to_string
-----------------
868778103681
generate_series
메서드 의 두 번째 인수 는 문자열의 길이를 지정합니다.
답변
이용하십시오 string_agg
!
SELECT string_agg (substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', ceil (random() * 62)::integer, 1), '')
FROM generate_series(1, 45);
MD5와 함께 이것을 사용하여 UUID도 생성하고 있습니다. random ()
정수 보다 비트가 더 많은 임의의 값을 원합니다 .
답변
기본적으로 활성화되지 않은 상태에서 핵심 확장 중 하나를 활성화 할 수 있습니다.
CREATE EXTENSION IF NOT EXISTS pgcrypto;
그러면 문이 임의의 문자열을 생성하는 gen_salt ()에 대한 간단한 호출이됩니다.
select gen_salt('md5') from generate_series(1,4);
gen_salt
-----------
$1$M.QRlF4U
$1$cv7bNJDM
$1$av34779p
$1$ZQkrCXHD
선행 번호는 해시 식별자입니다. 각각 고유 한 식별자가있는 여러 알고리즘을 사용할 수 있습니다.
- md5 : $ 1 $
- BF : $ 2a $ 06 $
- des : 식별자 없음
- xdes : _J9 ..
확장에 대한 추가 정보 :
- pgCrypto : http://www.postgresql.org/docs/9.2/static/pgcrypto.html
- 포함 된 확장 : http://www.postgresql.org/docs/9.2/static/contrib.html
편집하다
Evan Carrol이 지적했듯이 v9.4부터 다음을 사용할 수 있습니다. gen_random_uuid()