अफसोस की बात है, इसे आसानी से सरल अनोखे विरोधाभास/इंडेक्स (अगर इसे हल किया जा सकता है) के साथ आसानी से हल नहीं किया जा सकता है।
आप क्या जरूरत है, एक exclusionconstraint है: टक्कर की तरह कुछ के आधार पर कुछ पंक्तियों को बाहर करने की क्षमता है,। अद्वितीय बाधाएं केवल विशिष्ट बहिष्करण बाधाएं हैं (वे समानता टकराव पर आधारित हैं)। ARRAY[row1.cola, row1.colb] && ARRAY[row2.cola, row2.colb]
यह सूचकांक काम कर सकता है (वर्तमान में केवल gist
अनुक्रमित समर्थन:
तो, सिद्धांत रूप में, तुम बस हर row1
, जहां पहले से ही एक row2
, जिसके लिए यह अभिव्यक्ति सत्य है है बाहर करने की आवश्यकता बहिष्कार की कमी):
ALTER TABLE table_name
ADD CONSTRAINT table_name_exclusion
EXCLUDE USING gist ((ARRAY[cola, colb]) WITH &&);
लेकिन दुर्भाग्य से, वहाँ सरणियों के लिए कोई डिफ़ॉल्ट ऑपरेटर वर्ग (जो gist
का उपयोग करता है)। एक intarray
module है, जो केवल integer
सरणी के लिए एक प्रदान करता है, लेकिन text
सरणी के लिए कुछ भी नहीं है।
आप वास्तव में इस बाहर काम करना चाहते हैं, तो आप हमेशा range
types (f.ex. मैं आसन्न -|-
ऑपरेटर, जो सभी मामलों, जो unique
साथ संभाला नहीं जा सकता संभालती प्रयोग किया जाता) का दुरुपयोग कर सकते हैं ...
-- there is no built-in type for text ranges neither,
-- but it can can be created fairly easily:
CREATE TYPE textrange AS RANGE (
SUBTYPE = text
);
ALTER TABLE table_name
ADD CONSTRAINT table_name_exclusion
EXCLUDE USING gist ((textrange(least(cola, colb), greatest(cola, colb))) WITH -|-);
-- the exclusion constraint above does not handle all situations:
ALTER TABLE table_name
ADD CONSTRAINT table_name_check
CHECK (cola is distinct from colb); -- without this, empty ranges could be created,
-- which are not adjacent to any other range
CREATE UNIQUE INDEX table_name_unique
ON table_name ((ARRAY[least(cola, colb), greatest(cola, colb)]));
-- without this, duplicated rows could be created,
-- because ranges are not adjacent to themselves
... लेकिन मुझे डर है, आपकी मूल समस्या को थोड़ा डेटाबेस रिफैक्टरिंग के साथ हल किया जा सकता है; जो हमें प्रश्न पर लाता है: क्या समस्या है, क्या आप इसके साथ हल करना चाहते हैं?