निश्चित रूप से निष्क्रिय बनाम निष्क्रिय नहीं


90

मैंने इसे डेटाबेस सिस्टमDEFERRABLE में SQL कीवर्ड के बारे में पढ़ा - पूरी किताब

बाद वाला [NOT DEFERRABLE] डिफ़ॉल्ट है, और इसका मतलब है कि हर बार जब डेटाबेस संशोधन विवरण निष्पादित किया जाता है, तो बाधा की तुरंत जांच की जाती है, यदि संशोधन विदेशी-कुंजी बाधा का उल्लंघन कर सकता है।

हालांकि, अगर हम बाधा की घोषणा करते हैं , तो हमारे पास यह विकल्प होता है कि जब तक कि बाधा की जाँच करने से पहले कोई लेनदेन पूरा न हो जाए , तब तक प्रतीक्षा करें।

हम निश्चित रूप से निष्क्रिय या विशेष रूप से IMMEDIATE द्वारा शब्द DEFERRABLE का अनुसरण करते हैं । पूर्व मामले में, प्रत्येक लेनदेन के शुरू होने से ठीक पहले चेकिंग को स्थगित कर दिया जाएगा। बाद के मामले में, प्रत्येक विवरण के तुरंत बाद चेक बनाया जाएगा।

कैसे NOT DEFERRABLEअलग है DEFERRABLE INITIALLY IMMEDIATE? दोनों मामलों में, ऐसा लगता है, प्रत्येक व्यक्ति के बयान के बाद किसी भी बाधाओं की जाँच की जाती है।

जवाबों:


72

साथ DEFERRABLE INITIALLY IMMEDIATEजब आपको उसकी आवश्यकता आप मांग पर बाधाओं को स्थगित कर सकते हैं।

यह उपयोगी है यदि आप सामान्य रूप से स्टेटमेंट समय पर बाधाओं की जांच करना चाहते हैं, लेकिन उदाहरण के लिए बैच लोड कमिट समय तक चेकिंग को स्थगित करना चाहते हैं।

हालांकि विभिन्न DBMS के लिए बाधाओं को दूर करने के लिए वाक्यविन्यास अलग है।

साथ NOT DEFERRABLEआप कभी भी जाँच को तब तक के लिए स्थगित नहीं कर पाएंगे जब तक कि समय कम न हो जाए।


1
@romkyns: DEFERRABLEडिजाइनर का इरादा बताता है कि बाधा को दूर करना एक सार्थक या आवश्यक कार्रवाई है। यह डेटाबेस अवरोधों के विशाल बहुमत के लिए मामला नहीं है और सभी लेबलिंग के रूप में DEFERRABLEइस उपयोगी अंतर को खो देंगे।
onedaywhen

4
@onedaywhen मेरे एक सहकर्मी ने तब से एक अच्छा वैध कारण बताया है: आप किसी भी लेनदेन के किसी भी बिंदु पर गैर-बाधाकारी बाधाओं पर भरोसा कर सकते हैं, लेकिन लेन-देन शुरू होने पर ही निश्चित रूप से देखे जाते हैं।
रोमन स्टार्कोव

@RomanStarkov इसके अलावा, यह प्रदर्शन की बात है। NOT DEFERRABLEआमतौर पर सबसे तेज है।
तीजय दश

46

अन्य (सही) उत्तरों के अलावा, जब PostgreSQL की बात की जाती है , तो यह कहा जाना चाहिए कि:

  • साथ नहीं DEFERRABLE प्रत्येक पंक्ति सम्मिलित / अपडेट समय में चेक किया गया है

  • साथ DEFERRABLE (वर्तमान में तत्काल ) सभी पंक्तियों सम्मिलित / अपडेट करने के अंत में जाँच कर रहे हैं

  • साथ DEFERRABLE (वर्तमान में टाल ) सभी पंक्तियों लेन-देन के अंत में जाँच कर रहे हैं

इसलिए यह कहना सही नहीं है कि जब यह IMMEDIATE पर सेट किया जाता है, तो एक DEFERRABLE बाधा एक नहीं DEFERRABLE की तरह काम करता है।


आइए इस अंतर के बारे में विस्तार से जानें:

CREATE TABLE example(
    row integer NOT NULL,
    col integer NOT NULL,
    UNIQUE (row, col) DEFERRABLE INITIALLY IMMEDIATE
);

INSERT INTO example (row, col) VALUES (1,1),(2,2),(3,3);

UPDATE example SET row = row + 1, col = col + 1;

SELECT * FROM example;

यह सही ढंग से आउटपुट:

उत्पादन

लेकिन अगर हम नियमित रूप से निष्क्रिय अनुदेश हटाते हैं,

त्रुटि: डुप्लिकेट कुंजी मान अद्वितीय बाधा का उल्लंघन करता है "example_row_col_key" विवरण: कुंजी ("पंक्ति", कॉल) = (2, 2) पहले से मौजूद है। ********** त्रुटि **********

त्रुटि: डुप्लिकेट कुंजी मान अद्वितीय बाधा का उल्लंघन करता है "example_row_col_key" SQL स्थिति: 23505 विवरण: कुंजी ("पंक्ति", कर्नल) = (2, 2) पहले से मौजूद है।


ADDENDUM (12 अक्टूबर, 2017)

इस व्यवहार को वास्तव में यहाँ "खंडन" के रूप में प्रलेखित किया गया है :

इसके अलावा, PostgreSQL मानक के सुझाव के रूप में बयान के अंत में नहीं, तुरंत गैर-अप्रासंगिक विशिष्टता बाधाओं की जाँच करता है।


दिलचस्प। मुझे ऐसा लगता है कि मूल रूप से "IMMEDIATE" व्यवहार के लिए "NOT DEFERRABLE" व्यवहार को प्राथमिकता देने का कोई कारण नहीं है और यह Postgres के लिए अधिक क्षमाशील होने और "IMMEDIATE" की तरह DEFERRABLE नहीं बनाने के लिए समझ में आता है। जिस क्रम में एक अद्यतन विवरण में पंक्तियों को अद्यतन किया गया है वह भी दस्तावेज या अनुमान नहीं है जहाँ तक मुझे पता है, इसलिए इस मध्य-कथन बाधा जाँच का व्यवहार कम से कम आंशिक रूप से अनिर्दिष्ट नहीं है? मैं यह नहीं देख सकता कि कोई भी उस व्यवहार को क्यों चाहेगा - लेकिन शायद इसके लिए एक उचित उपयोग का मामला है जिसे देखने के लिए मेरे पास कल्पना की कमी है।
मार्क अमेरी

1
हां, मूल रूप से पसंद करने का एकमात्र कारण NOT DEFERRABLEगति है ( यहां देखें , गैर-आस्थगित विशिष्टता की कमी , "ध्यान रखें कि यह तत्काल विशिष्टता की जाँच की तुलना में काफी धीमा हो सकता है" )।
तीजय

साथ ही, DEFERRABLEबाधा को अन्य तालिकाओं में विदेशी कुंजियों के रूप में संदर्भित नहीं किया जा सकता है ( यहां देखें , अनुभाग पैरामीटर , "संदर्भित कॉलम गैर-डिफरेंबल यूनिक या प्राथमिक कुंजी बाधा के कॉलम को संदर्भित तालिका में होना चाहिए" )।
तीजय

1
अंगूठे के एक नियम के रूप में, अगर यह वास्तव में व्यावसायिक तर्क के लिए कोई फर्क नहीं पड़ता है, जब बाधा की जाँच की जाती है, तो क्या मुझे NOT DEFERRABLEबस इसका उपयोग करने के लिए डिफ़ॉल्ट होना चाहिए क्योंकि यह बेहतर प्रदर्शन करता है?
dvtan

1
हमारे ORM में अब हम निम्नलिखित नियमों का उपयोग करते हैं: 1) यदि बाधा पीके है, तो हम NOT DEFERRABLE2 का उपयोग करते हैं ) यदि कम से कम एक FK बाधा का संदर्भ देता है, तो हम NOT DEFERRABLE3 का भी उपयोग करते हैं ) अन्य मामलों में, हम उपयोग करते हैं DEFERRABLE INITIALLY IMMEDIATE। यह उन बाधाओं के प्रदर्शन को थोड़ा कम कर सकता है, लेकिन हमारे द्वारा उपयोग किए जाने वाले अन्य डीबीएमएस (ओरेकल, स्क्लस्वर) के साथ अधिकतम संगतता सुनिश्चित करता है। पीके और एफके एक मुद्दा नहीं है क्योंकि हम कभी भी उनके मूल्यों को अपडेट नहीं करते हैं (जो मुझे लगता है कि डीबी के लिए एक अच्छी प्रोग्रामिंग आदत है)।
तीजय

29

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

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


7

मुझे पार्टी में बहुत देर हो चुकी है लेकिन मैं इसे जोड़ना चाहता था - दिसंबर 2018 तक - केवल दो डेटाबेस जिन्हें मैं जानता हूं (और भी हो सकते हैं) इस मानक SQL सुविधा के कार्यान्वयन के कुछ स्तर प्रदान करते हैं :

Database    NOT DEFERRABLE  DEFERRABLE           DEFERRABLE 
                            INITIALLY IMMEDIATE  INITIALLY DEFERRED
----------  --------------  -------------------  ------------------
Oracle      N/A *1          Yes (default)        Yes
PostgreSQL  Yes (default)   Yes                  Yes
DB2         -               -                    -
SQL Server  -               -                    -
MySQL       -               -                    -
MariaDB     -               -                    -
SAP Sybase  -               -                    -
HyperSQL    -               -                    -
H2          -               -                    -
Derby       -               -                    -

* 1 भले ही ओरेकल 12 सी NOT DEFERRABLE बाधा राज्य स्वीकार करता है , यह वास्तव में इसे अनदेखा करता है और इसे काम करता है DEFERRABLE INITIALLY IMMEDIATE

जैसा कि आप देखते हैं, ओरेकल पहले प्रकार ( NOT DEFERRABLE) को लागू नहीं करता है , और यही कारण है कि ओरेकल (इस मामले में ओपी) का उपयोग करने वाले डेवलपर्स भ्रमित हो सकते हैं और पहले दो प्रकार के समकक्ष पर विचार कर सकते हैं।

दिलचस्प रूप से पर्याप्त ओरेकल और PostgreSQL का एक अलग डिफ़ॉल्ट प्रकार है। शायद इसके प्रदर्शन निहितार्थ हैं।


4

निश्चित नहीं है - आप बाधा जाँच को नहीं बदल सकते हैं, प्रत्येक विवरण के बाद oracle इसकी जाँच करता है (अर्थात सीधे कथन को सम्मिलित करने के बाद)।

निश्चित रूप से IMMEDIATE - नियमित रूप से प्रत्येक कथन के बाद दैवज्ञता की जाँच करता है। लेकिन, आप इसे प्रत्येक लेनदेन के बाद (यानी कमिट के बाद) बदल सकते हैं:

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