मुझे याद है कि जब PG9 अल्फा अवस्था में था तब लगभग एक समान बिंदु उठाया था। यहां टॉम लेन (हाई-प्रोफाइल पीजी कोर डेवलपर) का जवाब था:
https://archives.postgresql.org/pgsql-general/2010-01/msg00221.php
संक्षेप में:ठीक नहीं होगा।
यह कहने के लिए नहीं कि मैं आपके सुझाव से सहमत हूं कि वर्तमान व्यवहार एक बग है। इसे विपरीत कोण से देखें:यह NOT DEFERRABLE का व्यवहार है यह गलत है।
वास्तव में, इस अद्यतन में बाधा उल्लंघन किसी भी मामले में कभी नहीं होना चाहिए, क्योंकि अद्यतन के अंत में बाधा संतुष्ट है। कमांड के अंत में राज्य क्या मायने रखता है। एकल कथन के निष्पादन के दौरान मध्यवर्ती राज्यों को उपयोगकर्ता के सामने प्रकट नहीं किया जाना चाहिए।
ऐसा लगता है कि PostgreSQL प्रत्येक पंक्ति को अद्यतन करने और पहले डुप्लिकेट पर तुरंत विफल होने के बाद डुप्लिकेट की जांच करके गैर-आस्थगित बाधा को लागू करता है, जो अनिवार्य रूप से त्रुटिपूर्ण है। लेकिन यह एक ज्ञात समस्या है, शायद PostgreSQL जितनी पुरानी है। आजकल इसके लिए समाधान ठीक एक DEFERRABLE बाधा का उपयोग करना है। और इसमें कुछ विडंबना है कि आप इसे कमी के रूप में देख रहे हैं क्योंकि यह विफल होने में विफल रहता है, जबकि किसी तरह इसे पहली जगह में विफलता का समाधान माना जाता है!
PostgreSQL 9.1 के बाद से यथास्थिति का सारांश
-
NOT DEFERRABLEUNIQUEयाPRIMARY KEYबाधाओं की जाँच की जाती है प्रत्येक पंक्ति के बाद । -
DEFERRABLEबाधाएंIMMEDIATEपर सेट हैं (INITIALLY IMMEDIATEयाSET CONSTRAINTS. के माध्यम से ) चेक किए जाते हैं प्रत्येक कथन के बाद । -
DEFERRABLEबाधाएंDEFERREDपर सेट हैं (INITIALLY DEFERREDयाSET CONSTRAINTS. के माध्यम से ) चेक किए जाते हैं प्रत्येक लेनदेन के बाद ।
UNIQUE . के विशेष व्यवहार पर ध्यान दें / PRIMARY KEY बाधाओं। CREATE TABLE के लिए मैन्युअल पृष्ठ का हवाला देते हुए :
एक बाधा जो आस्थगित नहीं है, उसे तुरंत प्रत्येक आदेश के बाद की जांच की जाएगी ।
जबकि यह संगतता . में और नीचे बताता है Non-deferred uniqueness constraints के अंतर्गत अनुभाग :
जब एक UNIQUE या PRIMARY KEY बाधा आस्थगित नहीं है,PostgreSQL अद्वितीयता के लिए तुरंत जाँच करता है जब भी कोई पंक्ति डाली या संशोधित की जाती है। SQL मानक कहता है कि विशिष्टता को केवल कथन के अंत में लागू किया जाना चाहिए; इससे फर्क पड़ता है, उदाहरण के लिए, एक एकल कमांड कई प्रमुख मानों को अपडेट करता है। मानक-अनुपालन व्यवहार प्राप्त करने के लिए, बाधा को DEFERRABLE . के रूप में घोषित करें लेकिन आस्थगित नहीं (यानी, INITIALLY IMMEDIATE ) ध्यान रखें कि यह तत्काल विशिष्टता जाँच की तुलना में काफी धीमा हो सकता है।
बोल्ड जोर मेरा।
अगर आपको कोई FOREIGN KEY चाहिए कॉलम (स्तंभों) को संदर्भित करने के लिए बाधाएं, DEFERRABLE एक विकल्प नहीं है क्योंकि (प्रति दस्तावेज):
संदर्भित कॉलम संदर्भित तालिका में एक गैर-आस्थगित अद्वितीय या प्राथमिक कुंजी बाधा के कॉलम होने चाहिए।