Postgres for Insert 문에서 UUID를 생성 하시겠습니까?


367

내 질문은 다소 간단합니다. UUID의 개념을 알고 있으며 DB의 'store'에서 각 'item'을 참조하기 위해 하나를 생성하려고합니다. 합리적인 것 같습니까?

문제는 다음 줄이 오류를 반환한다는 것입니다.

honeydb=# insert into items values(
uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
ERROR:  function uuid_generate_v4() does not exist
LINE 2: uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
        ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

http://www.postgresql.org/docs/current/static/uuid-ossp.html 에서 페이지를 읽었습니다 .

여기에 이미지 설명을 입력하십시오

우분투 10.04 x64에서 Postgres 8.4를 실행하고 있습니다.


8
Postgres는 기본적으로 UUID 를 데이터 유형 으로 지원 하며 기본 키로 색인을 생성하고 사용할 수 있습니다. 그러나 열의 기본값을 설정하는 등 UUID 값 을 생성 하려면 Postgres 확장 (플러그인)이 필요합니다. Postgres의 많은 빌드 (배포)에는 이러한 확장이 포함되지만 확장은 활성화하지 않습니다. Craig Ringer의 정답을 참조하여 활성화하는 방법을 알아보십시오.
Basil Bourque

2
uuid-ossp가 설치되어 있고이 오류가 계속 발생하면 스키마 이름으로 함수 접두어를 입력하십시오.select dbo.uuid_generate_v4()
Richard

답변:


435

uuid-osspcontrib 모듈이므로 기본적으로 서버에로드되지 않습니다. 사용하려면 데이터베이스에로드해야합니다.

최신 PostgreSQL 버전 (9.1 이상)의 경우 다음과 같습니다.

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

그러나 9.0 이하에서는 대신 확장을로드하기 위해 SQL 스크립트를 실행해야합니다. 8.4의 contrib 모듈에 대한 설명서를 참조하십시오 .

대학원 9.1 및 최신 대신 읽어 현재의 contrib의 문서를 하고 CREATE EXTENSION. 이러한 기능은 8.4와 같은 9.0 또는 이전 버전에는 존재하지 않습니다.

패키지 버전의 PostgreSQL을 사용하는 경우 contrib 모듈 및 확장이 포함 된 별도의 패키지를 설치해야 할 수 있습니다. 패키지 관리자 데이터베이스에서 'postgres'및 'contrib'을 검색하십시오.


6
@advocate 당신은 배포판으로 포장 된 PostgreSQL을 사용하고 있습니다 apt-get install postgresql-contrib. 시도 apt-cache search postgresql |grep contrib원하는 패키지 이름을 찾습니다.
Craig Ringer

2
sudo apt-get install postgresql-contrib가 성공적으로 실행되었습니다. 그런 다음 psql -d dbname -f SHAREDIR / contrib / module.sql을 실행해야했으며 이제는 작동합니다 !!! uuid_generate_v1 ()을 선택하십시오. 지금 1을 반환합니다. 정말 고마워!
anon58192932

5
postgresql-contrib패키지를 설치하지 않으면 오류가 발생합니다. 오류 : 확장 제어 파일 "/usr/share/postgresql/9.3/extension/uuid-ossp.control"을 열 수 없습니다 : 해당 파일 또는 디렉토리가 없습니다.
Drew Noakes

1
Google에서 오류 문자열이 발생했을 때 해당 의견을 게시했습니다. 또한 우분투에 대한 특정 패키지 이름을 제공합니다.
Drew Noakes

2
Extensions에 uuid-ossp가있는 DB를 가져온 경우 uuid_generate_v4 ()가 작동하지 않을 수 있습니다. 이 경우 확장을 제거하고 다시 생성하면 작동합니다.
Dragos Rusu

302

확장 기능 없음 (속임수)

SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);

output>> c2d29867-3d0b-d497-9191-18a9d8ee7830

(최소 8.4 이상에서 작동)

  • clock_timestamp()설명 을 위해 @ Erwin Brandstetter에게 감사드립니다 .

유효한 v4 UUID가 필요한 경우

SELECT uuid_in(overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing to_hex(floor(random()*(11-8+1) + 8)::int)::text from 17)::cstring);

여기에 이미지 설명을 입력하십시오 * @Denis Stafichuk @Karsten@autronix 덕분에


또한 현대 Postgres에서는 다음을 간단히 캐스팅 할 수 있습니다.

SELECT md5(random()::text || clock_timestamp()::text)::uuid


5
PS를 추적하려면 : SELECTuuid_in(md5(random()::text || now()::text)::cstring);
Blaskovicz

4
@MattDiPasquale 아마도을 사용하는 것보다 "더 나은"것은 uuid-ossp아니지만 확장을 설치할 수있는 충분한 권한이없는 PostgreSQL 인스턴스에서 작업하고 있습니다.
Stefan Haberl

25
@JosephLennox : clock_timestamp()두 경우 모두 더 나은 대안입니다. 달리 now()또는 CURRENT_TIMESTAMP일시적이며 실제 현재 시간을 반환합니다. SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);또한 현대 Postgres에서는 다음을 간단히 캐스팅 할 수 있습니다 SELECT md5(random()::text || clock_timestamp()::text)::uuid.-더 많은 마법이 필요하지 않습니다. 사용 사례 : stackoverflow.com/a/8335376/939860
Erwin Brandstetter

17
아니. 이것이 전혀 효과가 없다면. UUID는 임의의 16 진 문자가 아닌 형식을 갖습니다. 첫 번째 그룹의 숫자는 intance를위한 uuid 버전입니다 (일반적으로 요즘 4 개). 응용 프로그램이 해당 숫자를 확인하여 처리하는 uuid 버전을 확인하고 그에 따라 무언가를 수행하면 코드에서 실패합니다.
Tuncay Göncüoğlu

7
@Tuncay Göncüoğlu : 유효한 v4 UUID를 생성하는 것은 매우 간단합니다 (문자열 오버레이 방식은 임의의 2 비트를 낭비 함) :select overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing '8' from 17)::uuid;
Karsten

75

Craig Ringer답변 이 맞습니다. 다음은 Postgres 9.1 이상에 대한 정보입니다.

확장 프로그램이 있습니까?

Postgres 설치 ( Postgres lingo 의 클러스터) 용으로 이미 확장 된 경우에만 확장을 설치할 수 있습니다 . 예를 들어, uuid-ossp 확장명 은 EnterpriseDB.com에서 친절하게 제공 하는 Mac OS X 용 설치 프로그램의 일부로 포함 된 것을 발견했습니다 . 수십 개의 확장 중 하나를 사용할 수 있습니다.

Postgres 클러스터에서 uuid-ossp 확장을 사용할 수 있는지 확인하려면 이 SQL을 실행하여 pg_available_extensions시스템 카탈로그 를 쿼리하십시오 .

SELECT * FROM pg_available_extensions;

확장 설치

해당 UUID 관련 확장 을 설치하려면 이 SQL에 표시된대로 CREATE EXTENSION 명령을 사용하십시오 .

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

주의 : 나는 반대로 문서화에도 불구하고 확장자 이름 주위에 QUOTATION MARK 문자가 필요하다는 것을 알았습니다.

SQL 표준위원회 또는 Postgres 팀은 해당 명령에 대해 이상한 이름을 선택했습니다. 내 생각에 그들은 "설치 확장"또는 "사용 확장"과 같은 것을 선택 했어야했다.

설치 확인

이 SQL을 실행하여 pg_extension시스템 카탈로그 를 조회하여 원하는 데이터베이스에 확장이 성공적으로 설치되었는지 확인할 수 있습니다 .

SELECT * FROM pg_extension;

기본값으로 UUID

자세한 내용은 질문 : Postgres의 UUID 열 기본값

올드 웨이

위의 정보는 Postgres 9.1에 추가 된 새로운 확장 기능을 사용합니다 . 이전 버전에서는 .sql 파일 에서 스크립트를 찾아 실행해야했습니다 . 확장 기능은 확장 기능 의 사용자 / 소비자 부분에 대한 작업을 줄 이도록 확장 작성자 에게 더 많은 작업을 제공하여 설치를보다 쉽게하도록 추가되었습니다 . 자세한 내용은 내 블로그 게시물 을 참조하십시오 .

UUID의 유형

그런데 질문의 코드는 함수를 호출합니다 uuid_generate_v4(). 이는 거의 모든 128 비트가 임의로 생성 되는 버전 4 로 알려진 유형을 생성합니다. 작은 행 집합에서는 제한적으로 사용하는 것이 좋지만 실제로 충돌 가능성을 없애려면 UUID의 다른 "버전"을 사용하십시오.

예를 들어, 원래 버전 1 은 호스트 컴퓨터 의 MAC 주소 와 현재 날짜-시간 및 임의의 숫자를 결합하므로 충돌 가능성은 거의 없습니다.

자세한 내용 은 관련 질문에 대한 답변 을 참조하십시오 .


1
CREATE EXTENSION IF NOT EXISTS ...확실하지 않고 확인하고 싶지 않은 경우 에도 사용할 수 있습니다 (예 : 스크립트)
Uwe Allner

2
버전 4 UUID는 "작은 행 집합에 대한 제한적인 사용"뿐만 아니라 거의 모든 크기의 데이터 집합에 적합합니다. 충돌 가능성이 50 %가 되려면 약 85 년 동안 초당 10 억 개의 UUID를 생성해야합니다 (또는 오늘날 가장 큰 데이터베이스보다 수천 배 큰 약 4 천 5 백만 테라 바이트의 데이터). NSA가 아닌 한, 버전 4는 모든 목적에 적합합니다. 반면에 버전 1은 MAC 주소가 순차적으로 할당되고 (스푸핑되거나 사용 불가능한) 사실로 인해 이후 버전이 도입 된 이유 중 하나입니다.
재즈

1
@BasilBourque v1의 문제는 올바르게 구현되었을 때 충돌 가능성이 아니라 잘못된 구현 가능성입니다. Wikipedia는 다음과 같이 말합니다. "버전 1 및 2 UUID의 고유성 ... 네트워크 카드 제조업체는 고유 한 MAC 주소를 카드에 올바르게 할당하는 데 의존합니다. 다른 제조 프로세스와 마찬가지로 오류가 발생할 수 있습니다." 또한 일부 컨테이너화 된 환경 또는 가상화 된 환경에서는 기본 하드웨어의 실제 MAC 주소를 사용할 수 없습니다. 많은 컨테이너가 동일한 MAC을 가지고 있지만 고유 한 clockseq 카운터를 가진 경우 해당 v1 UUID가 충돌 할 수 있습니다.
재즈

1
v1의 @BasilBourque 약점은 내 의견의 요점이 아닙니다. 원래의 대답은 v4가 v1보다 충돌 확률이 높기 때문에 v4가 큰 데이터 세트에 적합하지 않다는 것을 암시합니다. v1은 구현에 따라 달라지기 때문에 v1의 충돌 확률을 계산하기는 어렵지만 오해의 소지가 있거나 거짓 일 수 있습니다.
재즈

1
@BasilBourque 예를 들어, node-uuid 프로젝트는 4.6e18의 1과 두 개의 프로세스가 동일한 v1 UUID 시퀀스를 생성하도록 clockseq 카운터의 확률을 계산합니다. 이것은 작지만 v4의 즉각적인 충돌 가능성보다 훨씬 높으며 5.3e36의 1입니다. v4 UUID를 더 오래 생성할수록 충돌이 발생할 가능성이 높아지지만 v1에서는 그렇지 않지만 충돌 확률이 노드의 v1 구현을 초과하기 전에 15 억 개의 v4 UUID를 생성해야합니다. 대부분의 사람들은 테이블 당 15 억 2 천만 개의 레코드를 가지고 있지 않습니다.
재즈

61

pgcrypto 신장

Postgres 9.4부터이 pgcrypto모듈에는 gen_random_uuid()기능이 포함되어 있습니다. 이 함수는 난수 기반 버전 4 유형 UUID 중 하나를 생성 합니다.

아직 사용할 수없는 경우 contrib 모듈을 가져옵니다.

sudo apt-get install postgresql-contrib-9.4

pgcrypto모듈을 사용하십시오 .

CREATE EXTENSION "pgcrypto";

이제 gen_random_uuid()기능을 사용할 수 있어야합니다.

사용법 예.

INSERT INTO items VALUES( gen_random_uuid(), 54.321, 31, 'desc 1', 31.94 ) ;


모듈의 Postgres 문서에서uuid-ossp 인용하십시오 .

참고 : 임의로 생성 된 (버전 4) UUID 만 필요한 경우 pgcrypto 모듈에서 gen_random_uuid () 함수를 대신 사용하십시오.


3
예. 그러나 조각화에 대해 경고하고 대신 uuid-ossp를 제안하는 blog.starkandwayne.com/2015/05/23/… 도 참조하십시오 .
Malik A. Rumi

3
실제로 postgresql.org/message-id/…를 참조하십시오 . Postgres의 UUID 조각화 문제가 발생한 곳
Bob Kocisko

그러나 포스트 그레스는 위의 의견에 결정적 잘못된 링크 된 게시물을 제작, 최신 버전의 인덱스를 클러스터했다 않으며, 우리는 곧 다시 광장 1에 있습니다
마이클 Goldshteyn

1
@MichaelGoldshteyn : 아니오, Postgres 에는 클러스터 된 인덱스 가 없습니다 (Postgres 12 기준)
a_horse_with_no_name

3
ALTER TABLE table_name ALTER COLUMN id SET DEFAULT uuid_in((md5((random())::text))::cstring);

@ ZuzEL의 답변을 읽은 후 위 코드를 열 ID의 기본값으로 사용했으며 정상적으로 작동합니다.


1

다음 PostgreSQL 13은 확장 기능을 활성화 할 필요없이 기본적으로 gen_random_uuid () 를 지원합니다.

PostgreSQL에는 UUID를 생성하는 하나의 함수가 포함되어 있습니다.

gen_random_uuid ()  uuid

이 함수는 버전 4 (임의) UUID를 반환합니다. 이것은 가장 일반적으로 사용되는 UUID 유형이며 대부분의 응용 프로그램에 적합합니다.

db <> 바이올린 데모

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.