MyCql में डिलीट कैस्केड और ऑन अपडेट कैस्केड में अंतर


45

मैं MySQL डाटाबेस में दो तालिकाओं है parent, child। मैं मूल तालिका के आधार पर अपने बच्चे की तालिका में विदेशी कुंजी संदर्भ जोड़ने की कोशिश कर रहा हूं। क्या ON UPDATE CASCADEऔर के बीच कोई महत्वपूर्ण अंतर हैON DELETE CASCADE

माय पैरेंट टेबल

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

मेरा प्रश्न है: निम्नलिखित एसक्यूएल प्रश्नों में क्या अंतर है।

  1. ON DELETE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON DELETE CASCADE
    ) ENGINE=INNODB;
    
  2. ON UPDATE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON UPDATE CASCADE
    ) ENGINE=INNODB;
    
  3. ON UPDATE CASCADE ON DELETE CASCADE

    CREATE TABLE child (
            id INT, 
            parent_id INT,
            INDEX par_ind (parent_id),
            FOREIGN KEY (parent_id) 
                REFERENCES parent(id)
                ON UPDATE CASCADE ON DELETE CASCADE
        ) ENGINE=INNODB;
    

क्या प्रश्नों में कोई त्रुटि है? इन प्रश्नों (1,2 और 3) का क्या मतलब है ?? क्या वे वही हैं ???


1
ps <नाइटपिक> पूर्णता के लिए, जो आप ऊपर बता रहे हैं, वह DDL (डेटा परिभाषा भाषा) स्टेटमेंट्स हैं , न कि क्वेरीज़। आमतौर पर एक क्वेरी को DML (डेटा मैनिप्युलेशन लैंग्वेज
सेलेक्ट

पूर्णता के लिए फिर से एक और पीएस, मैंने सोचा कि डिफ़ॉल्ट क्या था। इसलिए मैंने अपडेट या डिलीट न होने पर एक बच्चा बनाया। तब क्या होता है कि आप एक ऐसे माता-पिता को न तो अपडेट कर सकते हैं और न ही हटा सकते हैं, जिस पर आश्रित बच्चा है। यह सही समझ में आता है, हालांकि MySQL हमेशा उस विशेष विशेषता :-) का मॉडल नहीं है
Vérace

जवाबों:


64

इस विषय पर एक बहुत अच्छा सूत्र यहां और यहां भी पाया जाना है । MySQL के लिए निश्चित गाइड, निश्चित रूप से, प्रलेखन, यहां पाया जाना है

SQL 2003 मानक में 5 अलग-अलग संदर्भ क्रियाएँ हैं:

  1. CASCADE
  2. प्रतिबंधित
  3. कोई कार्रवाई नहीं
  4. पूरा सेट
  5. डिफॉल्ट सेट करें

प्रश्न का उत्तर देने के लिए:

  1. CASCADE

    • ON DELETE CASCADEइसका मतलब है कि अगर अभिभावक का रिकॉर्ड डिलीट हो जाता है, तो किसी भी चाइल्ड रिकॉर्ड को भी डिलीट कर दिया जाता है। मेरी राय में यह अच्छा विचार नहीं है। आपको उन सभी डेटा पर नज़र रखनी चाहिए, जो कभी डेटाबेस में रहे हों, हालांकि यह TRIGGERएस का उपयोग करके किया जा सकता है । (हालांकि, नीचे टिप्पणी में चेतावनी देखें)।

    • ON UPDATE CASCADEइसका मतलब यह है कि अगर माता-पिता की प्राथमिक कुंजी को बदल दिया जाता है, तो बच्चे का मूल्य भी बदल जाएगा। मेरी राय में, एक महान विचार नहीं है। यदि आप PRIMARY KEYकिसी भी नियमितता (या यहां तक ​​कि!) के साथ बदल रहे हैं , तो आपके डिजाइन में कुछ गड़बड़ है। फिर से, टिप्पणियों को देखें।

    • ON UPDATE CASCADE ON DELETE CASCADEइसका मतलब है कि यदि आप UPDATE या DELETE माता-पिता, परिवर्तन बच्चे के लिए cascaded है। यह ANDपहले दो वक्तव्यों के परिणाम के आईएनजी के बराबर है ।

  2. प्रतिबंधित

    • RESTRICTइसका मतलब है कि माता-पिता को हटाने और / या अपडेट करने का कोई भी प्रयास एक त्रुटि फेंकने में विफल रहेगा। यह घटना में डिफ़ॉल्ट व्यवहार है जो एक संदर्भात्मक कार्रवाई स्पष्ट रूप से निर्दिष्ट नहीं है।

      एक के लिए ON DELETEया ON UPDATEकि निर्दिष्ट नहीं है, तो डिफ़ॉल्ट कार्यवाही हमेशा RESTRICT` है।

  3. कोई कार्रवाई नहीं

    • NO ACTION: मैनुअल से । मानक एसक्यूएल से एक कीवर्ड। MySQL में, के बराबर RESTRICT। यदि संदर्भ तालिका में संबंधित विदेशी कुंजी मान है, तो MySQL सर्वर पैरेंट टेबल के लिए डिलीट या अपडेट ऑपरेशन को अस्वीकार कर देता है। कुछ डेटाबेस सिस्टम में चेक आस्थगित है, और NO ACTIONएक आस्थगित चेक है। MySQL में, विदेशी कुंजी बाधाओं को तुरंत चेक किया जाता है, इसलिए NO ACTIONजैसा है वैसा ही है RESTRICT
  4. पूरा सेट

    • SET NULL- फिर से मैनुअल से। पेरेंट टेबल से पंक्ति हटाएं या अपडेट करें, और चाइल्ड टेबल में विदेशी कुंजी कॉलम या कॉलम सेट करें NULL। यह नहीं है विचारों का सबसे अच्छा IMHO, का कोई रास्ता नहीं है इसका मुख्य कारण वहाँ "समय-यात्रा" - यानी बच्चे तालिकाओं में वापस देख रही है और साथ रिकॉर्ड जोड़ NULLप्रासंगिक माता पिता रिकॉर्ड के साथ रों - या तो CASCADEया उपयोग TRIGGERरों ट्रैक करने के लिए टेबल प्रवेश करने को भरने के लिए परिवर्तन (लेकिन, टिप्पणियां देखें)।
  5. डिफॉल्ट सेट करें

    • SET DEFAULT। फिर भी SQL मानक का एक और (संभावित रूप से बहुत उपयोगी) हिस्सा जो MySQL को लागू करने से परेशान नहीं है! डेवलपर को एक मान निर्दिष्ट करने के लिए अनुमति देता है कि किस पर एक विदेशी या कॉलम को सेट करें। InnoDB और NDB एक SET DEFAULTखंड के साथ तालिका परिभाषाओं को अस्वीकार कर देंगे ।

जैसा कि ऊपर उल्लेख किया गया है, आपको यहां दस्तावेज देखने के लिए कुछ समय बिताना चाहिए ।


8
मुझे आपका पूरा उत्तर पसंद है लेकिन मैं इस कथन से असहमत हूं। "आपको उन सभी डेटा का ट्रैक रखना चाहिए जो कभी डेटाबेस में रहे हैं" - यह वास्तव में डेटाबेस के डिज़ाइन और उद्देश्यों पर निर्भर है। उदाहरण के लिए एक रेसिपी डेफिनिशन (मैं खाना नहीं बोल रहा हूं - सिस्टम कॉन्फिगरेशन की तरह अधिक) जब रेसिपी की परिभाषा हटाई जाती है तो इससे उस रेसिपी के जुड़े बच्चों को रखने का कोई मतलब नहीं है - यह सिर्फ बिना किसी कारण के लिए डीबी को उड़ा देता है। मशीन सिस्टम के लिए भी काम की मेज - मुझे अब डेटा की आवश्यकता नहीं है; प्रक्रिया करें और इससे छुटकारा पाएं। इसके अलावा आपका जवाब शानदार है।
StixO

2
@StixO के समान ही मुझे भी यह उत्तर पसंद है, लेकिन मैं प्राथमिक कुंजी को बदलने से असहमत हूं। निश्चित रूप से ऐसे डिज़ाइन हैं जहां यह एक बुरा विचार होगा लेकिन जब आप एक वितरित डेटाबेस में आते हैं, तो यह बहुत ही वांछनीय हो सकता है कि प्राथमिक कुंजी एक रिकॉर्ड की पहचान खोए बिना फिर से असाइन किए जाने के लिए स्वतंत्र हैं।
गार्ट क्लैबोर्न

"यह मेरी राय में एक अच्छा विचार नहीं है। आपको उन सभी डेटा पर नज़र रखनी चाहिए जो कभी डेटाबेस में रहे हों।" - यकीन नहीं होता कि मैं आपकी बात समझ गया हूं। यदि आप 'डिलीट ऑन' कैस्केडिंग कर रहे हैं, तो आपने पहले ही तय कर लिया है कि आपको कुछ हटाने की आवश्यकता है। यदि आप कुछ भी कभी नहीं हटाने का फैसला करते हैं, तो कुछ भी नहीं होगा। हालांकि यह होने का लाभ यह है कि आपके आवेदन में आप यह सुनिश्चित कर सकते हैं कि जब आप एक विदेशी आईडी के साथ रिकॉर्ड की तलाश करते हैं, तो आप जानते हैं कि यह वहां होगा, और आपके डेटाबेस को नष्ट करने वाली कोई भी अनाथ पंक्तियां नहीं होनी चाहिए जो आपको हटाने का फैसला करना चाहिए कुछ कुछ।
जेफ रयान

यहाँ तर्क स्थानों में बहुत दोषपूर्ण है, और हमारे नए जीडीपीआर दुनिया में और भी अधिक। मैं इस धारणा से सहमत हूं कि यदि प्राथमिक कुंजी बदल रही है, तो यह कुछ गलत होने का संकेत हो सकता है।
चक ले बट

यदि आप किसी भी नियमितता (या यहां तक ​​कि सभी!) के साथ प्राथमिक कुंजी बदल रहे हैं, तो आपके डिजाइन में कुछ गड़बड़ है। क्या आपको लगता है कि UPDATE CASCADE की कुंजी या नाम के मान को बदल देता है?
बिलाल बेगुएरदज

8

ये दोनों क्रमशः किए जाने वाले कार्य हैं, जब मूल तालिका पर संदर्भित रिकॉर्ड इसकी आईडी को बदल देता है और जब यह हटा दिया जाता है।

यदि आप निष्पादित करते हैं:

UPDATE parent SET id = -1 WHERE id = 1;

और कम से कम एक रिकॉर्ड है childजिसके साथ parent_id = 1, 1) विफल हो जाएगा; 2 और 3) के मामलों में, parent_id = 1 के साथ सभी रिकॉर्ड्स parent_id = -1 में अपडेट किए जाते हैं।

यदि आप निष्पादित करते हैं:

DELETE FROM parent WHERE id = 1;

और कम से कम एक रिकॉर्ड है childजिसके साथ parent_id = 1, 2) विफल हो जाएगा; 1) और 3) के मामलों में, के साथ सभी रिकॉर्ड parent_id = 1हटा दिए जाते हैं।

3) वाक्यात्मक रूप से सही है।

पूर्ण प्रलेखन मैनुअल पर पाया जा सकता है


6

मेरे पास पिछले उत्तरों पर टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है। इसलिए मैंने सोचा कि मैं थोड़ा विस्तार करूँगा।

1) DELETE CASCADE पर इसका मतलब है कि यदि मूल रिकॉर्ड हटा दिया जाता है, तो किसी भी संदर्भित बाल रिकॉर्ड को भी हटा दिया जाता है। RESTRICT पर UPDATE डिफॉल्ट पर, जिसका अर्थ है कि पैरेंट रिकॉर्ड पर UPDATE विफल होगा।

2) RESTRICT को DELETE एक्शन डिफॉल्ट पर, जिसका अर्थ है कि पैरेंट रिकॉर्ड पर DELETE विफल हो जाएगा। जब अद्यतन माता-पिता के रिकॉर्ड को अद्यतन किया जाता है, तो सभी अद्यतन बच्चे के रिकॉर्ड को अपडेट करेंगे।

3) ऊपर 1) और 2) में CASCADE क्रियाएँ देखें।

पैरेंट रिकॉर्ड आईडी का उपयोग विदेशी कुंजी के रूप में (चाइल्ड टेबल में) - अनुभव कहता है कि ए) यदि आईडी ऑटो-जेनरेट किए गए अनुक्रम संख्या हैं, तो उन्हें विदेशी कुंजी के रूप में उपयोग न करें। इसके बजाय कुछ अन्य अद्वितीय मूल कुंजी का उपयोग करें। ख) यदि आईडी GUID हैं, तो उन्हें विदेशी कुंजियों के रूप में उपयोग करना ठीक है। जब आप निर्यात करते हैं और रिकॉर्ड आयात करते हैं या रिकॉर्ड को किसी अन्य डेटाबेस में कॉपी करते हैं, तो आपको इस सुझाव में ज्ञान दिखाई देगा। जब वे विदेशी कुंजियों के रूप में संदर्भित होते हैं, तो डेटा माइग्रेशन के दौरान ऑटो-जेनरेट किए गए अनुक्रम संख्या से निपटना बहुत बोझिल हो जाता है।

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