कैस्केड की अच्छी व्याख्या (ON DELETE / UPDATE) व्यवहार


98

मैं हर रोज स्कीमा डिजाइन नहीं करता, लेकिन जब मैं करता हूं, तो मैं प्रशासन को आसान बनाने के लिए कैस्केड अपडेट / डिलीट को सही तरीके से सेटअप करने की कोशिश करता हूं। मैं समझता हूं कि कैस्केड कैसे काम करता है, लेकिन मैं कभी याद नहीं कर सकता कि कौन सी मेज है।

उदाहरण के लिए, अगर मेरे पास दो टेबल हैं - Parentऔर Child- Childउस संदर्भ पर एक विदेशी कुंजी के साथ Parentऔर ON DELETE CASCADE, कौन से रिकॉर्ड एक कैस्केड को ट्रिगर करते हैं और कौन से रिकॉर्ड कैस्केड द्वारा हटा दिए जाते हैं? मेरा पहला अनुमान होगा कि Childरिकॉर्ड हटाए जाने पर Parentरिकॉर्ड हटा दिए जाएंगे , क्योंकि Childरिकॉर्ड रिकॉर्ड पर निर्भर करते Parentहैं, लेकिन ON DELETEअस्पष्ट है; इसका मतलब यह हो सकता है कि Parentरिकॉर्ड Childहटाए जाने पर रिकॉर्ड को हटा दिया जाए, या इसका मतलब यह हो सकता है कि Childरिकॉर्ड Parentको हटा दिया गया है। तो कौन सा है?

काश वाक्य रचना था ON PARENT DELETE, CASCADE, ON FOREIGN DELETE, CASCADEअस्पष्टता दूर करने के लिए कुछ इसी तरह या। किसी को भी यह याद करने के लिए कोई mnemonics है?

जवाबों:


138

अगर आपको पसंद है Parentऔर Childशर्तें और आपको लगता है कि उन्हें याद रखना आसान है, तो आपको इसका अनुवाद पसंद आ सकता ON DELETE CASCADEहैLeave No Orphans!

जिसका अर्थ है कि जब कोई Parentपंक्ति हटा दी जाती है (मार दी जाती है), तो कोई भी अनाथ पंक्ति Childतालिका में जीवित नहीं रहनी चाहिए । मूल पंक्ति के सभी बच्चे मारे गए (हटाए गए) हैं, भी। यदि इनमें से किसी भी बच्चे के पोते हैं (एक अन्य विदेशी कुंजी के माध्यम से एक अन्य तालिका में) और वहां ON DELETE CASCADEपरिभाषित किया गया है, तो उन्हें मार दिया जाना चाहिए, (और सभी वंशज, जब तक कि कैस्केड प्रभाव परिभाषित हो।)

FOREIGN KEYबाधा खुद भी रूप में वर्णित किया जा सकता है Allow No Orphans!(पहली जगह में)। कोई Childकभी अनुमति दी जानी चाहिए बच्चे तालिका में (लिखित) अगर यह एक नहीं है Parent(मूल तालिका में एक पंक्ति)।

संगति के ON DELETE RESTRICTलिए, (कम एग्रेसिव) में अनुवाद किया You Can't Kill Parents!जा सकता है। केवल नि: संतान पंक्तियों को मारा जा सकता है (हटा दिया गया है)।


3
मुझे लगता है कि कुछ अभी भी सादृश्य में गायब है। क्या एक बच्चे के एक से अधिक माता-पिता नहीं हो सकते? इस मामले में एक माता-पिता की हत्या बच्चे को अनाथ बना देगी?
Jus12

7
@ Jus12 नहीं, विदेशी कुंजी बाधाएं केवल 1 माता-पिता के साथ काम करती हैं। यह इस पहलू के बारे में एक अच्छा सादृश्य नहीं है।
ypercube y

1
@ypercube: क्या इसकी अनुमति नहीं है? Order(custID, itemID, orderID)जहाँ तालिका custIDमें प्राथमिक कुंजी को संदर्भित करता है Customersऔर तालिका में प्राथमिक कुंजी को itemIDसंदर्भित करता है ItemsOrderदो माता-पिता नहीं होंगे ?
15:12 पर Jus12

4
@ Jus12 कि अनुमति है, लेकिन यह 2 विदेशी महत्वपूर्ण बाधाओं होगा। फिर हर बच्चे (आदेश) में एक माता-पिता (ग्राहक) और एक माता-पिता (वस्तु) होगा। 2 एफके के व्यवहार हालांकि भिन्न हो सकते हैं। (इसलिए, उदाहरण के लिए, यह हो सकता है कि ग्राहकों को मारने से उनके सभी (आदेश) बच्चे मारे जाएंगे, लेकिन वस्तुओं को मारने से उनके आदेश नहीं मारे जाएंगे।)
ypercubeᵀᴹ

1
यदि हम "अनाथ" नहीं कहते हैं, तो अभिभावक सादृश्य अभी भी काम कर सकता है। यदि एक बच्चे के प्रवेश पर दो अलग-अलग माता-पिता के दो संदर्भ हैं, तो यह अभी भी एक तलाकशुदा जोड़े के बच्चे के रूप में देखा जा सकता है। प्रतिबंध: "मैं आपको मेरी माँ को मारने नहीं दूंगा" कैस्केड: "यदि आप मेरे पिताजी को मारते हैं, तो मैं भी मर जाऊंगा"
क्रिस्टोफर मैकगोवन

31

उदाहरण के लिए, यदि मेरे पास दो टेबल हैं - पेरेंट और चाइल्ड - जहां चाइल्ड रिकॉर्ड्स पेरेंट रिकॉर्ड्स के स्वामित्व में हैं, तो किस टेबल को ON DELETE CASCADE की आवश्यकता है?

विदेशी मुद्रा में विदेशी कुंजी घोषणा में एक वैकल्पिक खंड है। तो यह विदेशी प्रमुख घोषणा के साथ जाता है । (मतलब, "बच्चे" तालिका में।)

... इसका मतलब यह हो सकता है कि चाइल्ड रिकॉर्ड डिलीट होने पर पेरेंट रिकॉर्ड को डिलीट कर दें, या इसका मतलब पेरेंट डिलीट होने पर चाइल्ड रिकॉर्ड डिलीट कर सकता है। तो कौन सा है?

विदेशी कुंजी घोषणा की व्याख्या करने का एक तरीका यह है, "इस कॉलम के सभी वैध मूल्य 'that_column' से 'in_table_' में आते हैं।" जब आप "बच्चे" तालिका में एक पंक्ति हटाते हैं, तो कोई भी परवाह नहीं करता है। यह डेटा अखंडता को प्रभावित नहीं करता है।

जब आप "पैरेंट" टेबल से "that_table" से एक पंक्ति हटाते हैं - आप "चाइल्ड" टेबल के लिए संभावित मानों से एक वैध मान हटाते हैं। डेटा अखंडता बनाए रखने के लिए, आपको "बच्चे" तालिका में कुछ करना होगा । कैस्केडिंग डिलीट एक ऐसी चीज है जिसे आप कर सकते हैं।


2

एसक्यूएल: २०११

के लिए पांच विकल्प हैं ON DELETE, और ON UPDATEयह लागू हो सकते हैं FOREIGN KEY। इन्हें <referential actions>सीधे SQL: 2011 युक्ति से बुलाया जाता है

  • ON DELETE CASCADE: यदि संदर्भित तालिका की एक पंक्ति हटा दी जाती है, तो संदर्भ तालिका की सभी मिलान पंक्तियाँ हटा दी जाती हैं।
  • ON DELETE SET NULL: यदि संदर्भित तालिका की एक पंक्ति हटा दी जाती है, तो संदर्भित तालिका के सभी मिलान पंक्तियों में सभी संदर्भित स्तंभों को शून्य पर सेट किया जाना है।
  • ON DELETE SET DEFAULT: यदि संदर्भित तालिका की एक पंक्ति को हटा दिया जाता है, तो सभी संदर्भ स्तंभों की सभी मिलान पंक्तियों में स्तंभ के डिफ़ॉल्ट मान पर सेट होने के लिए संदर्भित करता है।
  • ON DELETE RESTRICT: यह संदर्भित तालिका की एक पंक्ति को हटाने के लिए निषिद्ध है यदि उस पंक्ति में संदर्भ तालिका में कोई मिलान पंक्तियाँ हैं।
  • ON DELETE NO ACTION (डिफ़ॉल्ट) : कोई संदर्भात्मक हटाने की कार्रवाई नहीं है; संदर्भित अवरोध केवल एक बाधा जाँच निर्दिष्ट करता है।

विदेशी कुंजी आश्रित संबंध स्थापित करती है। यह <referential action>निर्धारित करता है कि संबंध भंग होने पर क्या होता है।

उदाहरण / रूपक / व्याख्या

इस उदाहरण के लिए, हम समाज और अर्थव्यवस्था के सामान्य मॉडल को स्वीकार करेंगे: जहां हर businessएक कंपनी है जो एक के bourgeoisieमाध्यम से संबंध बनाए रखती है fatcat_owner

CREATE TABLE bourgeoisie(
  fatcat_owner varchar(100) PRIMARY KEY
);
INSERT INTO bourgeoisie(fatcat_owner) VALUES
  ( 'Koch Brothers' );

CREATE TABLE business (
  name         varchar(100),
  fatcat_owner varchar(100) REFERENCES bourgeoisie
);
INSERT INTO business(name, fatcat_owner)
  VALUES ('Georgia-Pacific', 'Koch Brothers');

अगर सभी अपने तरीके से businessसीधे प्रभावित होते हैं तो आप मजदूरों की क्रांति के बाद क्या करते हैं जब आप एस को शुद्ध करते हैं और एक वर्गहीन समाज रखते हैं?bourgeoisiefatcat_ownerfatcat_owner

-- Viva la revolución 
BEGIN;
  DELETE FROM bourgeoisie;
END;

आपके पास यहां कुछ विकल्प हैं,

  • क्रांति बंद करो। एसक्यूएल भाषा में, RESTRICT। कुछ लोगों का मानना ​​है कि यह कम बुराई है, लेकिन वे आमतौर पर गलत हैं।
  • इसे जाने की अनुमति दें। यदि ऐसा होता है जब क्रांति होती है तो एसक्यूएल आपको चार विकल्प देता है,

    • SET NULL-- इसे खाली छोड़ें। कौन जानता है, हो सकता है कि पूंजीवाद को फिर से स्थापित किया bourgeoisieजाए और कुलीन वर्गों का रोल भरें fatcat_owners। महत्वपूर्ण नोट, कॉलम होना चाहिए NULLABLE(नहीं NOT NULL) या ऐसा कभी नहीं हो सकता है।
    • SET DEFAULT- शायद तुम एक DEFAULTकि यह संभाला था? A DEFAULTफ़ंक्शन को कॉल कर सकता है। हो सकता है कि आपका स्कीमा पहले से ही क्रांति-तैयार हो।
    • CASCADE- कोई डैमेज कंट्रोल नहीं है। अगर bourgeoisieजाता है, तो करता है business। यदि किसी व्यवसाय के पास होना आवश्यक है fatcat_pig, तो कभी-कभी यह एक businessतालिका में गैर-व्यवसाय के बजाय डेटा को खोने के लिए अधिक समझ में आता है ।
    • NO ACTION- यह अनिवार्य रूप से चेक में देरी करने का एक तरीका है, MySQL में यह इससे अलग नहीं है RESTRICT, लेकिन PostgreSQL में, आप कर पाएंगे

      -- Not a real revolution.
      -- requires constraint be DEFERRABLE INITIALLY DEFERRED
      BEGIN;
        SET CONSTRAINTS ALL DEFERRED;
        DELETE FROM bourgeoisie;
        INSERT INTO bourgeoisie VALUES ( 'Putin' );
        UPDATE business SET fatcat_pig = 'Putin';
      END;
      

      ऐसी प्रणाली में, लेन-देन के शुरू होने से पहले ही बाधा को मान्य किया जाता है। इसका परिणाम क्रांति को रोकना हो सकता है, लेकिन आप कुछ हद तक "वसूली" के लिए - लेन-देन कर सकते हैं।


क्या referencedटेबल का मतलब पैरेंट टेबल और referencingटेबल का मतलब चाइल्ड टेबल है?
sg552

@ sg552 हाँ, आपने इसे सही ढंग से समझा।
informatik01

0

एक साधारण महामारी होगी

यहां माता-पिता के मामले [डिलीट करके] डिलीट करें

इससे आपको पता चलता है कि कौन सा डिलीट ( पेरेंट को डिलीट करता है) कैस्केड हो जाता है , जहां ON DELETE CASCADE स्टेटमेंट (बच्चे पर) जाता है, और जो डिलीट हो जाता है (बच्चा)।


-3

ठीक है, शायद हम वाक्य रचना को युक्तिसंगत बना सकते हैं। आइए एक पायथन उदाहरण लेते हैं:

class Parent(self):
    # define parent's fields

class Child(self):    
    # define child's fields
    parent_pk_is_childs_foreign_key = models.ForeignKey(Parent, on_delete=models.CASCADE)

यह पंक्ति जो कहती है कि जनक का on_delete है (जो गलती से बयान में उल्लेख किया गया है), कृपया बच्चे पर विलोपन को रोकें। इसीलिए CASCADE स्टेटमेंट को बाल स्तर पर परिभाषित किया गया है, यह उन बच्चों को चिह्नित करता है जिन्हें हटाने की आवश्यकता है

उदाहरण के लिए यदि आपके पास एक और वर्ग था

class GrownUpChild(self):    
        # define grown up child's fields
        parent_pk_is_childs_foreign_key = models.ForeignKey(Parent, on_delete=models.DO_NOTHING)

यह संरचना स्पष्ट रूप से बताएगी कि किन बच्चों को हटाने की जरूरत है (चाइल्ड) और जिन्हें रहना है (GrownUpChild) अनाथ

[संपादित करें: चर्चा के संदर्भ को देखते हुए, विशेष रूप से on_delete = model.CASCADE आदि के मामलों में], वास्तव में यह अक्सर एक वांछित माता-पिता के बच्चों को छोड़ने के लिए एक वांछित व्यवहार होता है, जो ऑडिटिंग और रिपोर्टिंग कारणों के साथ-साथ आकस्मिक रूप से ठीक हो जाता है। हटाए गए। [निश्चित रूप से एंटरप्राइज़ स्तर सॉफ्टवेयर ऐसे व्यवहार के आसपास बनाया जाएगा और हटाए गए अभिलेखों को हटा दिया जाएगा = 1 के बजाय वास्तव में उन्हें हटा रहा है और सामने के अंत के लिए किसी भी प्रश्न में उन्हें शामिल नहीं करेगा, कुछ विशेष रूप से डिज़ाइन की गई रिपोर्ट को घटाता है। इसके अलावा इसमें डेटाबेस से हटाए गए == 1 रिकॉर्ड को शुद्ध करने का एक कार्य होगा, जिसे आमतौर पर यूआई प्रशासक द्वारा निष्पादित किया जाएगा, अक्सर डेटाबेस व्यवस्थापक की ओर से किसी भी भागीदारी से बचना होगा।]


1
'वास्तव में, यह ऑडिट और रिपोर्टिंग कारणों के साथ-साथ एक आकस्मिक माता-पिता के बच्चों को छोड़ने के लिए एक वांछित व्यवहार है, साथ ही साथ आकस्मिक विलोपन को पुनर्प्राप्त करना है ' - यह एक (साने) डेटाबेस में विनाशकारी होगा।
dezso

@ इनपुट आपके इनपुट के लिए धन्यवाद हालाँकि, कई एंटरप्राइज़ स्तर CRM सिस्टम ठीक वैसा ही करते हैं।
जॉर्ज मोगिलेव्स्की

टीबीएच जो इसे और अधिक समझदार नहीं बनाता है। मुझे एक बार इस तरह के दृष्टिकोण के परिणामस्वरूप गंदगी को ठीक करने का काम मिला - तनख्वाह के अलावा कोई खुशी नहीं।
dezso

आप एक सामान्य डेटाबेस व्यवस्थापक की तरह आवाज करते हैं :) मैं आपकी बात पूरी तरह से सुन सकता हूं। सॉफ्टवेयर जो मैंने ऊपर उल्लेख किया है, वह वास्तव में, हटाए गए = 1 को मैन्युअल रूप से हटाने के लिए एक फ़ंक्शन है इसलिए यह कॉल करने के लिए ऐप के व्यवस्थापक पर निर्भर है। आम तौर पर डेटाबेस व्यवस्थापक भी इस पहलू को बनाए रखने में शामिल नहीं है। और इसके अलावा, पूरे सॉफ्टवेयर का डेटाबेस क्लास कॉन्सेप्ट के आसपास बनाया गया है, इसलिए यह हमेशा क्रूड ऑपरेशंस में डिलीट किए गए झंडे की जांच करता है
जॉर्ज मोगिलेव्स्की

हां, यह एक ज्ञात और समझदार पैटर्न है - लेकिन फिर आपको संभवतः इसे प्रतिबिंबित करने के लिए ऊपर दिए गए शब्दों को बदलना चाहिए।
dezso
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.