Postgresql: सशर्त रूप से अद्वितीय बाधा


116

मैं एक बाधा जोड़ना चाहूंगा जो केवल एक तालिका के एक हिस्से में एक स्तंभ पर विशिष्टता को लागू करती है।

ALTER TABLE stop ADD CONSTRAINT myc UNIQUE (col_a) WHERE (col_b is null);

WHEREभाग ऊपर इच्छाधारी सोच है।

ऐसा करने का कोई तरीका? या मुझे रिलेशनल ड्राइंग बोर्ड में वापस जाना चाहिए?


2
आम तौर पर किया। "आंशिक अनूठे सूचकांक" देखें
क्रेग रिंगर

11
@yvesonline नहीं, यह एक नियमित अद्वितीय बाधा है। पोस्टर एक आंशिक अद्वितीय बाधा चाहता है ।
क्रेग रिंगर

जवाबों:


186

PostgreSQL एक आंशिक (यानी सशर्त) UNIQUEबाधा को परिभाषित नहीं करता है - हालांकि, आप एक आंशिक अद्वितीय सूचकांक बना सकते हैं । PostgreSQL अद्वितीय बाधाओं को लागू करने के लिए अद्वितीय अनुक्रमित का उपयोग करता है, इसलिए प्रभाव समान है, आप बस में सूचीबद्ध बाधा नहीं देखेंगे ।information_schema

CREATE UNIQUE INDEX stop_myc ON stop (col_a) WHERE (col_b is NOT null);

आंशिक सूचकांक देखें ।


24
उत्तम! यह स्पष्ट नहीं है कि "बाधा" एक बाधा के रूप में नहीं दिखती है, लेकिन फिर भीERROR: duplicate key value violates unique constraint "stop_myc"
EoghanM

7
यह ध्यान देने योग्य है कि यह FKs रेसेन्निग बनाने की अनुमति नहीं देगा जो आंशिक रूप से अद्वितीय क्षेत्र है।
22

11
यह भी ध्यान देने योग्य है कि यह सूचकांक प्रभाव स्थगित नहीं किया जा सकता है। यदि आपको बल्क अपडेट करने की आवश्यकता है तो यह एक समस्या पेश कर सकता है क्योंकि प्रत्येक पंक्ति के बाद विशिष्टता की जांच की जाती है, न कि इस तरह के बयान के बाद कि यह एक बाधा के लिए होगी या लेनदेन के बाद यह एक अड़चन बाधा के लिए होगी।
ऋषि 88

37

यह पहले ही कहा जा चुका है कि PG आंशिक (यानी सशर्त) UNIQUE बाधा को परिभाषित नहीं करता है। प्रलेखन यह भी कहता है कि एक अद्वितीय बाधा को एक तालिका में जोड़ने का पसंदीदा तरीका ADD CONSTRAINT अनोखा सूचकांक है

एक तालिका में एक अद्वितीय बाधा जोड़ने का पसंदीदा तरीका ALTER TABLE ... ADD CONSTRAINT है। अद्वितीय बाधाओं को लागू करने के लिए अनुक्रमित के उपयोग को एक कार्यान्वयन विवरण माना जा सकता है जिसे सीधे एक्सेस नहीं किया जाना चाहिए। हालांकि, एक को पता होना चाहिए कि अद्वितीय स्तंभों पर मैन्युअल रूप से अनुक्रमित बनाने की कोई आवश्यकता नहीं है; ऐसा करने से स्वचालित रूप से बनाए गए इंडेक्स की नक़ल होगी।

बहिष्करण बाधाओं का उपयोग करके इसे लागू करने का एक तरीका है , (इस समाधान के लिए @dukelion धन्यवाद)

आपके मामले में ऐसा लगेगा

ALTER TABLE stop ADD CONSTRAINT myc EXCLUDE (col_a WITH =) WHERE (col_b IS null);

उस दृष्टिकोण पर आप इंडेक्स विधि को परिभाषित करने के लिए "उपयोग" नहीं करते हैं, ताकि यह बहुत धीमा हो या पोस्टग्रेज उस पर एक डिफ़ॉल्ट इंडेक्स बनाता है? यह विधि विहित विकल्प है, लेकिन बेहतर विकल्प कभी नहीं! मुझे लगता है कि आपको उस विकल्प को बेहतर बनाने के लिए सूचकांक के साथ एक "उपयोग" खंड की आवश्यकता होगी।
नातान मेदिरोस

10
धीमे रहने पर, अपवर्जित समाधान का लाभ यह है कि यह असाध्य है (और कथन के अंत तक डिफ़ॉल्ट डिफर्स द्वारा)। इसके विपरीत, स्वीकृत अद्वितीय सूचकांक समाधान को स्थगित नहीं किया जा सकता (और हर पंक्ति परिवर्तन के बाद जांच की जाती है)। इसलिए एक थोक अपडेट अक्सर संभव नहीं होता है क्योंकि अपडेट के दौरान चरण अद्वितीय अवरोध का उल्लंघन करते हैं, भले ही यह परमाणु अपडेट स्टेटमेंट के अंत में उल्लंघन न हो।
ऋषि 88

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