2011-04-11 7 views
104

मैं कुछ PostgreSQL तालिका बनाने में देख रहा हूँ और मैं इस पर ठोकर खाई:एसक्यूएल, पोस्टग्रेस ओआईडी, वे क्या हैं और वे उपयोगी क्यों हैं?

CREATE TABLE (
... 
) WITH (OIDS = FALSE); 

मैं postgres द्वारा प्रदान प्रलेखन पढ़ सकते हैं और मैं OOP से ऑब्जेक्ट पहचानकर्ता की अवधारणा को पता है, लेकिन अभी भी मैं समझ नहीं है,

  • ऐसे पहचानकर्ता डेटाबेस में क्यों उपयोगी होंगे?
  • प्रश्न कम करने के लिए?
  • इसका उपयोग कब किया जाना चाहिए?

उत्तर

115

ओआईडी मूल रूप से आपको सिस्टम पंक्ति में निहित प्रत्येक पंक्ति के लिए एक अंतर्निहित, वैश्विक रूप से अद्वितीय आईडी प्रदान करता है (उपयोगकर्ता-स्थान कॉलम के विपरीत)। यह उन टेबलों के लिए आसान है जहां आपके पास प्राथमिक कुंजी नहीं है, डुप्लिकेट पंक्तियां हैं, उदाहरण के लिए, उदाहरण के लिए, यदि आपके पास दो समान पंक्तियों वाली तालिका है, और आप दोनों में से सबसे पुराने को हटाना चाहते हैं, तो आप इसे कर सकते हैं ओड कॉलम

मेरे अनुभव में, सुविधा आम तौर पर (क्योंकि वे अमानक रहे शायद भाग में) सबसे postgres समर्थित अनुप्रयोगों में अप्रयुक्त है, और their use is essentially deprecated:

PostgreSQL 8.1 default_with_oids में डिफ़ॉल्ट रूप से बंद है ; पोस्टग्रेएसक्यूएल के पूर्व संस्करणों में, यह डिफ़ॉल्ट रूप से चालू था।

उपयोगकर्ता तालिकाओं में OIDs के उपयोग पदावनत माना जाता है, इसलिए अधिकांश प्रतिष्ठानों इस चर विकलांग छोड़ देना चाहिए। अनुप्रयोग को किसी विशेष तालिका के लिए ओआईडी की आवश्यकता है जब तालिका बनाते समय ओआईडीएस के साथ निर्दिष्ट होना चाहिए। यह चर पुराना अनुप्रयोगों के साथ संगतता के लिए सक्षम हो सकता है जो व्यवहार का पालन नहीं करते हैं।

+24

oids अद्वितीय होने की गारंटी नहीं है। दस्तावेज़ों से: "बड़े या लंबे समय तक रहने वाले डेटाबेस में, काउंटर के चारों ओर लपेटना संभव है। इसलिए, यह मानना ​​बुरा व्यवहार है कि ओआईडी अद्वितीय हैं, जब तक आप यह सुनिश्चित करने के लिए कदम उठाते हैं कि यह मामला है।" – radiospiel

+7

चारों ओर लपेटने से यह भी संकेत मिलता है कि आप केवल ओआईडी पर आधारित दो पंक्तियों के पुराने को हटा नहीं सकते थे, क्योंकि निचले ओआईडी वाले एक लपेटने के आसपास हो सकता है। –

+0

ओआईडी वैश्विक स्तर पर अद्वितीय नहीं हैं, उपरोक्त प्रति टिप्पणियां, और न ही 2011 में जब यह उत्तर लिखा गया था। इसके अलावा, सिस्टम ऑब्जेक्ट्स के लिए ओआईडी की आवश्यकता होती है, इसलिए पंक्ति काउंटर पर सभी ओआईडी का उपयोग करने से डेटाबेस को ओआईडी को नई टेबल (तालिका के लिए, इसकी पंक्तियों के साथ) निर्दिष्ट करने में मदद नहीं होती है। साथ ही, इस बात पर विचार करें कि एक गायक 4-बाइट पूर्णांक काउंटर वास्तव में आपके डेटाबेस में प्रत्येक तालिका के लिए पर्याप्त होगा या नहीं। – FuzzyChef

9

OID के Postgres with के लिए भी प्रयोग में हैं बड़े objects (हालांकि कुछ लोगों को बड़ी वस्तुओं वैसे भी आम तौर पर उपयोगी नहीं हैं तर्क है)। इन्हें द्वारा बड़े पैमाने पर भी उपयोग किया जाता है। उदाहरण के लिए उनका उपयोग TOAST द्वारा किया जाता है जो 8KB BYTEA (आदि) से अधिक एक अलग भंडारण क्षेत्र (पारदर्शी रूप से) तक स्टोर करता है जिसका उपयोग डिफ़ॉल्ट रूप से सभी तालिका द्वारा किया जाता है। "सामान्य" उपयोगकर्ता तालिकाओं से जुड़े उनके प्रत्यक्ष उपयोग मूल रूप से deprecated है।

ओड प्रकार वर्तमान में एक हस्ताक्षरित चार-बाइट पूर्णांक के रूप में लागू किया गया है। इसलिए, यह बड़े डेटाबेस में, या यहां तक ​​कि बड़ी व्यक्तिगत तालिकाओं में डेटाबेस-व्यापी विशिष्टता प्रदान करने के लिए पर्याप्त नहीं है। इसलिए, प्राथमिक कुंजी के रूप में उपयोगकर्ता द्वारा निर्मित तालिका के ओआईडी कॉलम का उपयोग करके निराश किया जाता है। ओआईडी का उपयोग केवल सिस्टम टेबल के संदर्भों के लिए किया जाता है।

स्पष्ट रूप से ओआईडी अनुक्रम "करता है" लपेटता है अगर यह 4 बी 6 से अधिक हो जाता है। तो संक्षेप में यह एक वैश्विक काउंटर है जो लपेट सकता है। यदि यह लपेटता है, तो इसका उपयोग होने पर कुछ मंदी शुरू हो सकती है और अद्वितीय मूल्यों के लिए "खोजी गई" आदि हो सकती है।

भी देखें https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

2

अपने डेटाबेस तालिकाओं से सभी OIDs निकालने के लिए, तो आप इस लिनक्स स्क्रिप्ट का उपयोग कर सकते हैं:

पहले, PostgreSQL सुपर उपयोगकर्ता के रूप में प्रवेश:

sudo su postgres 

अब इस स्क्रिप्ट को चलाने, आपके साथ डेटाबेस नाम के साथ YOUR_DATABASE_NAME बदल रहा है:

for tbl in `psql -qAt -c "select schemaname || '.' || tablename from pg_tables WHERE schemaname <> 'pg_catalog' AND schemaname <> 'information_schema';" YOUR_DATABASE_NAME` ; do psql -c "alter table $tbl SET WITHOUT OIDS" YOUR_DATABASE_NAME ; done 

मैंने अपने सभी ओआईडी को हटाने के लिए इस स्क्रिप्ट का उपयोग किया, क्योंकि Npgsql 3.0 इसके साथ काम नहीं करता है, और यह PostgreSQL के लिए अब महत्वपूर्ण नहीं है।

संबंधित मुद्दे