इंसर्ट स्टेटमेंट डालने के लिए पोस्टग्रुप्स में यूयूआईडी बनाना?


367

मेरा सवाल बल्कि सरल है। मैं एक यूयूआईडी की अवधारणा से अवगत हूं और मैं अपने डीबी में एक 'स्टोर' से प्रत्येक 'आइटम' को संदर्भित करने के लिए एक उत्पन्न करना चाहता हूं। उचित लगता है?

समस्या यह है कि निम्नलिखित लाइन में त्रुटि है:

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

यहां छवि विवरण दर्ज करें

मैं Ubuntu 10.04 x64 पर Postgres 8.4 चला रहा हूं।


8
पोस्टग्रुप मूल रूप से यूयूआईडी को डेटा प्रकार के रूप में समर्थन करता है , यहां तक ​​कि अनुक्रमित होने और प्राथमिक कुंजी के रूप में उपयोग करने में सक्षम है। लेकिन एक यूयूआईडी मूल्य उत्पन्न करने के लिए , जैसे कि एक कॉलम के लिए डिफ़ॉल्ट मान स्थापित करने के लिए, आपको पोस्टग्रेज एक्सटेंशन (एक प्लगइन) की आवश्यकता है। Postgres के कई बिल्ड (वितरण) में ऐसा एक्सटेंशन शामिल है लेकिन एक्सटेंशन को सक्रिय नहीं करते हैं। क्रेग रिंगर द्वारा सही उत्तर देखें कि इसे कैसे सक्रिय किया जाए।
बेसिल बॉर्क

2
यदि आपके पास uuid-ossp स्थापित है और आप अभी भी इस त्रुटि को अपने स्कीमा नाम के साथ फ़ंक्शन को उपसर्ग करने की कोशिश करते हैं, जैसेselect dbo.uuid_generate_v4()
रिचर्ड

जवाबों:


435

uuid-osspएक कंट्राब मॉड्यूल है, इसलिए यह डिफ़ॉल्ट रूप से सर्वर में लोड नहीं होता है। इसका उपयोग करने के लिए आपको इसे अपने डेटाबेस में लोड करना होगा।

आधुनिक PostgreSQL संस्करणों (9.1 और नए) के लिए यह आसान है:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

लेकिन 9.0 और नीचे के लिए आपको एक्सटेंशन लोड करने के लिए SQL स्क्रिप्ट को चलाना होगा। 8.4 में कंट्रिब मॉड्यूल के लिए प्रलेखन देखें ।

पीजी 9.1 और नए के लिए इसके बजाय वर्तमान कंट्रिब डॉक्स और पढ़ें CREATE EXTENSION। ये सुविधाएं आपके 8.4 की तरह 9.0 या पुराने संस्करणों में मौजूद नहीं हैं।

यदि आप PostgreSQL के एक पैकेज्ड संस्करण का उपयोग कर रहे हैं, तो आपको एक अलग पैकेज स्थापित करने की आवश्यकता हो सकती है जिसमें कंट्रीब्यूल मॉड्यूल और एक्सटेंशन हों। 'पोस्टग्रेज' और 'कंट्रीब' के लिए अपने पैकेज मैनेजर डेटाबेस को खोजें।


6
@advocate आप एक डिस्ट्रो-पैकेज्ड PostgreSQL का उपयोग कर रहे हैं ताकि आप बस apt-get install postgresql-contribया समान होने में सक्षम हों । apt-cache search postgresql |grep contribइच्छित पैकेज नाम खोजने का प्रयास करें ।
क्रेग रिंगर

2
sudo apt-get Install postgresql-contrib सफलतापूर्वक चला है। तब मुझे psql -d dbname -f SHAREDIR / contrib / मॉड्यूल.sql चलाना था और अब यह काम करता है !!! uuid_generate_v1 () का चयन करें; 1 अब देता है। बहुत बहुत धन्यवाद!
anon58192932

5
ध्यान दें कि यदि आप postgresql-contribपैकेज स्थापित नहीं करते हैं , तो आपको त्रुटि मिलेगी: त्रुटि: एक्सटेंशन नियंत्रण फ़ाइल नहीं खोल सका "/usr/share/postgresql/9.3/extension/uuid-ossp.control": ऐसी कोई फ़ाइल या निर्देशिका नहीं
आकर्षित नोक

1
मैंने उस टिप्पणी को Google पर त्रुटि स्ट्रिंग के रूप में पोस्ट किया है। कम से कम उबंटू के लिए भी यह एक विशिष्ट पैकेज का नाम देता है।
ड्रू नोक

2
यदि आपने पहले से एक्सटेंशन में ubid-ossp वाला db आयात किया है, तो uuid_generate_v4 () काम नहीं कर सकता है। अगर ऐसा है, तो एक्सटेंशन को हटा दें, और इसे फिर से बनाएं और इसे काम करना चाहिए।
ड्रैगोस रूसु

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 को धन्यवाद


इसके अलावा, आधुनिक पोस्टग्रेज में, आप बस कास्ट कर सकते हैं:

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


5
अपने PS का अनुसरण करने के लिए: SELECTuuid_in(md5(random()::text || now()::text)::cstring);
Blaskovicz

4
@MattDiPasquale शायद किसी भी मायने में "बेहतर" उपयोग करने से बेहतर नहीं है uuid-ossp, लेकिन मैं उदाहरण के लिए एक PostgreSQL उदाहरण पर काम कर रहा हूं जहां मेरे पास एक्सटेंशन स्थापित करने के लिए पर्याप्त विशेषाधिकार नहीं हैं।
स्टीफन हैबरल

25
@JosephLennox: clock_timestamp()इसके लिए बेहतर विकल्प है। इसके विपरीत now()या CURRENT_TIMESTAMPयह अस्थिर है और वास्तविक वर्तमान समय देता है। SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);इसके अलावा, आधुनिक पोस्टग्रेज में, आप बस कास्ट कर सकते हैं: SELECT md5(random()::text || clock_timestamp()::text)::uuid- अधिक जादू की कोई आवश्यकता नहीं है। केस-केस: stackoverflow.com/a/8335376/939860
Erwin Brandstetter

17
नहीं। अगर यह उसके सरासर भाग्य पर काम करता है। एक UUID का एक प्रारूप है, इसका न केवल यादृच्छिक हेक्स वर्ण एक साथ फेंका जाता है। 3 वें समूह की पहली संख्या इरादे के लिए uuid संस्करण है (आमतौर पर इन दिनों 4)। यदि आपका एप्लिकेशन उस अंक की जाँच करता है, तो यह देखने के लिए कि उसका संस्करण किस संस्करण से काम कर रहा है, और तदनुसार कुछ करें, तो यह आपके कोड में विफल हो जाएगा।
टुनके गोनकुओलू

7
@ टुनके गोनकुओलू: यह वैध वी 4 यूयूआईडी (स्ट्रिंग ओवरले दृष्टिकोण बेतरतीबी के 2 बिट्स बर्बाद करता है) उत्पन्न करने के लिए काफी सीधा है:select overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing '8' from 17)::uuid;
कार्स्टन

75

क्रेग रिंगर द्वारा जवाब सही है। यहां पोस्टग्रैजेस 9.1 और बाद के लिए थोड़ी अधिक जानकारी दी गई है ...

एक्सटेंशन उपलब्ध है?

आप केवल एक एक्सटेंशन स्थापित कर सकते हैं यदि यह पहले से ही आपके पोस्टग्रेज इंस्टॉलेशन ( पोस्टग्रेज लिंगो में आपका क्लस्टर ) के लिए बनाया गया है । उदाहरण के लिए, मुझे एंटरप्राइज़.कॉम द्वारा प्रदान किए गए कृपया मैक ओएस एक्स के लिए इंस्टॉलर के भाग के रूप में शामिल uuid-ossp एक्सटेंशन मिला । एक में से कोई कुछ दर्जन एक्सटेंशन उपलब्ध हो सकता है।

यह देखने के लिए कि आपके पोस्टग्रेज क्लस्टर में uuid-ossp एक्सटेंशन उपलब्ध है, pg_available_extensionsसिस्टम कैटलॉग को क्वेरी करने के लिए इस SQL ​​को चलाएं :

SELECT * FROM pg_available_extensions;

एक्सटेंशन स्थापित करें

उस Urel पर-आधारित एक्सटेंशन को स्थापित करने के लिए , इस SQL ​​में देखे गए CREATE EXTENSION कमांड का उपयोग करें :

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

खबरदार: मुझे इसके विपरीत एक्सटेंशन नाम के आसपास उद्धरण मार्क वर्णों की आवश्यकता थी, इसके विपरीत प्रलेखन के बावजूद।

SQL मानक समिति या पोस्टग्रेज टीम ने उस आदेश के लिए एक विषम नाम चुना। मेरे दिमाग में, उन्हें "INSTALL EXTENSION" या "USE EXTENSION" जैसा कुछ चुनना चाहिए था।

स्थापना को सत्यापित करें

आप pg_extensionसिस्टम कैटलॉग को क्वेरी करने के लिए इस SQL ​​को चलाकर वांछित डेटाबेस में एक्सटेंशन को सफलतापूर्वक स्थापित कर सकते हैं :

SELECT * FROM pg_extension;

डिफ़ॉल्ट मान के रूप में UUID

अधिक जानकारी के लिए, प्रश्न देखें: Postgres में UUID कॉलम के लिए डिफ़ॉल्ट मान

पुराना रास्ता

उपरोक्त जानकारी पोस्टग्रैजेस 9.1 में जोड़े गए नए एक्सटेंशन फीचर का उपयोग करती है । पिछले संस्करणों में, हमें .sql फ़ाइल में स्क्रिप्ट ढूंढनी और चलाना था । एक्सटेंशन की सुविधा को इंस्टॉलेशन को आसान बनाने के लिए जोड़ा गया था, एक्सटेंशन के उपयोगकर्ता / उपभोक्ता की ओर से कम काम के लिए एक्सटेंशन के निर्माता के लिए थोड़ा अधिक काम करना । अधिक चर्चा के लिए मेरा ब्लॉग पोस्ट देखें ।

UUIDs के प्रकार

वैसे, प्रश्न में कोड फ़ंक्शन को कॉल करता है uuid_generate_v4()। यह एक प्रकार 4 संस्करण के रूप में जाना जाता है, जहां लगभग 128 बिट्स यादृच्छिक रूप से उत्पन्न होते हैं। हालांकि यह पंक्तियों के छोटे सेट पर सीमित उपयोग के लिए ठीक है, यदि आप टकराव की किसी भी संभावना को समाप्त करना चाहते हैं, तो UUID के दूसरे "संस्करण" का उपयोग करें।

उदाहरण के लिए, मूल संस्करण 1 मेजबान कंप्यूटर के मैक पते को वर्तमान तिथि-समय और एक मनमानी संख्या के साथ जोड़ता है , टकराव की संभावना व्यावहारिक रूप से शून्य है।

अधिक चर्चा के लिए, संबंधित प्रश्न पर मेरा उत्तर देखें ।


1
और CREATE EXTENSION IF NOT EXISTS ...अगर आप निश्चित नहीं हैं तो भी इस्तेमाल कर सकते हैं और (जैसे स्क्रिप्ट में) चेक नहीं करना चाहते हैं
Uwe Allner

2
संस्करण 4 यूयूआईडी लगभग किसी भी आकार के डेटा सेट के लिए ठीक हैं, न केवल "पंक्तियों के छोटे सेट पर सीमित उपयोग।" आपको लगभग or५ वर्षों (या ४५ मिलियन टेराबाइट डेटा, आज के सबसे बड़े डेटाबेस से हजारों गुना बड़ा) के लिए प्रति सेकंड १ बिलियन यूयूआईडी उत्पन्न करना होगा, यहां तक ​​कि टक्कर की ५०% संभावना भी। जब तक आप एनएसए नहीं हैं, तब तक संस्करण 4 किसी भी उद्देश्य के लिए ठीक है। दूसरी ओर, संस्करण 1, इस तथ्य से ग्रस्त है कि मैक पते क्रमिक रूप से असाइन किए गए हैं (और अक्सर स्पूफ या अनुपलब्ध हैं), जो बाद के संस्करणों को पेश किए जाने का एक हिस्सा है।
जैज

1
@BasilBourque v1 के साथ मुद्दा टकराव की संभावना नहीं है जब सही ढंग से लागू किया जाता है, तो यह गलत कार्यान्वयन की संभावना है। जैसा कि विकिपीडिया यह कहता है: "संस्करण 1 और 2 यूयूआईडी की विशिष्टता ... नेटवर्क कार्ड निर्माताओं पर भी निर्भर करता है कि वे अपने कार्ड में अनूठे मैक पते को ठीक से असाइन कर रहे हैं, जो अन्य विनिर्माण प्रक्रियाओं की तरह त्रुटि के अधीन है।" इसके अलावा, कुछ कंटेनरीकृत या वर्चुअलाइज्ड वातावरण में, अंतर्निहित हार्डवेयर से सही मैक पते उपलब्ध नहीं हैं। यदि कई कंटेनरों में एक ही मैक है लेकिन उनके स्वयं के घड़ी काउंटर हैं, तो उनके v1 UUIDs टकरा सकते हैं।
जैज

1
हालांकि v1 में @BasilBourque कमजोरियां मेरी टिप्पणी का मुख्य बिंदु नहीं हैं। आपके मूल उत्तर का तात्पर्य है कि v4 टकराव की अधिक संभावना के कारण बड़े डेटासेट के लिए उपयुक्त नहीं है। यह भ्रामक और संभवतः गलत है, हालांकि v1 के लिए टकराव की संभावना की गणना करना कठिन है क्योंकि यह कार्यान्वयन-निर्भर है।
जैज

1
@BasilBourque उदाहरण के लिए, नोड-uuid परियोजना उनके घड़ीसाज़ काउंटर के समान होने की संभावना की गणना करती है (ताकि दो प्रक्रियाएं v1 UUIDs के समान अनुक्रम उत्पन्न करें) 4.6e18 में 1। यह छोटा है, हाँ, लेकिन v4 में तात्कालिक टकराव की संभावना से बहुत अधिक है, जो 5.3e36 में 1 है। जाहिर है कि जब आप v4 UUIDs उत्पन्न करते हैं, तो टकराव की संभावना अधिक होती है, जो कि v1 के सही नहीं है, लेकिन नोड के v1 कार्यान्वयन से अधिक टकराव की संभावना से पहले आपको 1.52 बिलियन v4 UUIDs उत्पन्न करना होगा। अधिकांश लोगों के पास प्रति तालिका 1.52 बिलियन रिकॉर्ड नहीं है।
जैज

61

pgcrypto एक्सटेंशन

Postgres 9.4 तक, pgcryptoमॉड्यूल में gen_random_uuid()फ़ंक्शन शामिल है । यह फ़ंक्शन यादृच्छिक-संख्या आधारित संस्करण 4 प्रकार के UUID में से एक बनाता है ।

कंट्राब मॉड्यूल प्राप्त करें, यदि पहले से उपलब्ध नहीं है।

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 ) ;


मॉड्यूल पर पोस्टग्रेज डॉकuuid-ossp से उद्धरण ।

नोट: यदि आपको केवल बेतरतीब ढंग से उत्पन्न (संस्करण 4) यूयूआईडी की आवश्यकता है, तो इसके बजाय pgcrypto मॉड्यूल से gen_random_uuid () फ़ंक्शन का उपयोग करने पर विचार करें।


3
हां, लेकिन यह भी देखें। blog.starkandwayne.com/2015/05/23/… जहां वे विखंडन के बारे में चेतावनी देते हैं और इसके बजाय uuid-ossp का सुझाव देते हैं।
मलिक ए। रूमी

3
वास्तव में, postgresql.org/message-id/… देखें, जहां पोस्टग्रेज में
यूआईडी

लेकिन पोस्टग्रेज में नवीनतम संस्करण में क्लस्टर इंडेक्स होते हैं, जो पोस्ट को उपरोक्त टिप्पणी से जोड़कर अनिर्णायक और गलत बनाते हैं और हम सही वर्ग 1 में वापस आ गए हैं
माइकल गोल्डसेन

1
@MichaelGoldshteyn: नहीं, पोस्टग्रेज में क्लस्टर इंडेक्स नहीं है (पोस्टग्रैस 12 के रूप में)
a_horse_with_no_name

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

@ ज़ुज़ेल के उत्तर को पढ़ने के बाद, मैंने उपरोक्त कोड को कॉलम आईडी के डिफ़ॉल्ट मान के रूप में उपयोग किया और यह ठीक काम कर रहा है।


1

आगामी PostgreSQL 13 किसी भी एक्सटेंशन को सक्षम करने की आवश्यकता के बिना natively gen_random_uuid () का समर्थन करेगा :

UgID को उत्पन्न करने के लिए PostgreSQL में एक फ़ंक्शन शामिल है:

gen_random_uuid ()  uuid

यह फ़ंक्शन 4 संस्करण (यादृच्छिक) UUID लौटाता है। यह यूयूआईडी का सबसे अधिक इस्तेमाल किया जाने वाला प्रकार है और अधिकांश अनुप्रयोगों के लिए उपयुक्त है।

db <> फिडेल डेमो

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.