2009-09-26 17 views
311

मैं नियमित रूप से "डिलीट कैस्केड" का उपयोग करता हूं लेकिन मैं कभी भी "अद्यतन कैस्केड पर" उपयोग नहीं करता क्योंकि मुझे यह सुनिश्चित नहीं है कि यह किस स्थिति में उपयोगी होगा।"अद्यतन अद्यतन कैस्केड" का उपयोग कब करें

चर्चा के लिए कुछ कोड देखें।

CREATE TABLE parent (
    id INT NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (id) 
); 

CREATE TABLE child (
    id INT NOT NULL AUTO_INCREMENT, parent_id INT, 
    INDEX par_ind (parent_id), 
    FOREIGN KEY (parent_id) 
     REFERENCES parent(id) 
     ON DELETE CASCADE 
); 

"चालू हटाना कैस्केड" के लिए, यदि एक id साथ एक माता पिता हटा दी जाती है, parent_id = parent.id के साथ बच्चे में एक रिकॉर्ड स्वचालित रूप से हटा दिया जाएगा। यह कोई समस्या नहीं होनी चाहिए।

  1. इसका मतलब यह है जब माता पिता की id अद्यतन किया जाता है कि "अद्यतन CASCADE पर" एक ही बात करेंगे?

  2. हैं (1) सच है, इसका मतलब है अगर parent.id जब यह AUTO_INCREMENT है या हमेशा TIMESTAMP होना करने के लिए सेट की तरह updatable नहीं है (या अद्यतन किया जा कभी नहीं होगा) "अद्यतन CASCADE पर" का उपयोग करने की कोई जरूरत नहीं है। क्या वह सही है?

  3. यदि (2) सच नहीं है, तो हमें किस प्रकार की स्थिति में "अद्यतन कैस्केड पर" उपयोग करना चाहिए?

  4. क्या होगा यदि मैं (किसी कारण से) child.parent_id को कुछ मौजूदा नहीं होने के लिए अद्यतन करता हूं, तो क्या यह स्वचालित रूप से हटा दिया जाएगा?

परीक्षण ठीक है, मुझे पता है, इसके बाद के संस्करण प्रश्न के कुछ हो सकता है programmically को समझने के लिए लेकिन मैं यह भी है कि अगर यह के किसी भी डेटाबेस विक्रेता पर निर्भरशील है या नहीं पता करना चाहते हैं।

कृपया कुछ प्रकाश डालें।

+1

यह भी देखें: http://stackoverflow.com/questions/6894162/postgresql-how-to-compact-renumber-id-for-all-tables-and-reset-sequences-to-max –

उत्तर

352

यह सच है कि यदि आपकी प्राथमिक कुंजी केवल पहचान मूल्य ऑटो वृद्धि हुई है, तो आपके पास ऑन अपडेट कैस्केड के लिए कोई वास्तविक उपयोग नहीं होगा।

हालांकि, मान लीजिए कि आपकी प्राथमिक कुंजी 10 अंकों का यूपीसी बार कोड है और विस्तार के कारण, आपको इसे 13 अंकों के यूपीसी बार कोड में बदलने की जरूरत है। उस स्थिति में, अद्यतन कैस्केड पर आपको प्राथमिक कुंजी मान और किसी भी तालिका को बदलने की अनुमति होगी जिसमें मूल्य के लिए विदेशी कुंजी संदर्भ होंगे, तदनुसार बदल दिया जाएगा।

# 4 के संदर्भ में, यदि आप बच्चे आईडी को किसी ऐसे चीज़ में बदलते हैं जो मूल तालिका में मौजूद नहीं है (और आपके पास संदर्भित अखंडता है), तो आपको एक विदेशी कुंजी त्रुटि प्राप्त करनी चाहिए।

+4

बस उपयोग करना था 'अद्यतन कैस्केड' पर एक पुरानी तालिका में प्राथमिक कुंजी को अपडेट करने के लिए जो स्वत: वृद्धि वाली कुंजी का उपयोग नहीं करता –

63
  1. हाँ, यह मतलब है कि उदाहरण के लिए यदि आप इस सेटिंग UPDATE parent SET id = 20 WHERE id = 10 10 के सभी बच्चों PARENT_ID के भी 20

  2. को अपडेट किया जाएगा आप क्षेत्र विदेशी कुंजी को संदर्भित करता है अद्यतन नहीं करते हैं करते हैं, की आवश्यकता नहीं है

  3. किसी भी अन्य उपयोग के बारे में सोच नहीं सकते।

  4. आप ऐसा नहीं कर सकते क्योंकि विदेशी कुंजी बाधा विफल हो जाएगी।

20

मुझे लगता है कि आप काफी अंक किसी न किसी है!

यदि आप डेटाबेस डिज़ाइन का सर्वोत्तम अभ्यास करते हैं और आपकी प्राथमिक कुंजी कभी भी अद्यतन नहीं होती है (जो मुझे लगता है कि हमेशा वैसे भी मामला होना चाहिए), तो आपको वास्तव में ON UPDATE CASCADE खंड की आवश्यकता नहीं है।

जेड एक अच्छा मुद्दा बनाया, कि यदि आप एक प्राकृतिक कुंजी (अपने डेटाबेस तालिका से एक नियमित रूप से क्षेत्र जैसे) अपने प्राथमिक कुंजी के रूप में उपयोग, तब वहाँ कुछ स्थितियों जहाँ आप अपनी प्राथमिक कुंजी अद्यतन करने की आवश्यकता हो सकती है । एक और हालिया उदाहरण आईएसबीएन (इंटरनेशनल स्टैंडर्ड बुक नंबर) होगा जो 10 से 13 अंकों + वर्णों से बहुत पहले नहीं बदला गया था।

इस मामले में आप अपने प्राथमिक कुंजी के रूप सरोगेट (जैसे कृत्रिम सिस्टम-जनित) कुंजी (जो सभी में मेरी पसंदीदा विकल्प लेकिन सबसे दुर्लभ अवसरों होगा) का उपयोग करना चाहते हैं नहीं है।

तो अंत में: यदि आपकी प्राथमिक कुंजी कभी नहीं बदली जाती है, तो आपको कभी भी ON UPDATE CASCADE खंड की आवश्यकता नहीं है। अगर हम यह सोचते हैं कर रहे हैं कि माता-पिता कुंजी से अपडेट किए जाने नहीं है किन परिस्थितियों में अद्यतन CASCADE पर लागू होता है:

मार्क

+0

"कृत्रिम रूप से सिस्टम-जेनरेट की गई" कुंजी क्या है? UUIDs? – HPWD

+0

@ एचपीडब्ल्यूडी: केवल एक "कृत्रिम" कुंजी (एक मान जो आपके वास्तविक डेटा पर आधारित नहीं है या व्युत्पन्न नहीं है) जो सिस्टम द्वारा उत्पन्न होता है - यह * एक GUID, या एक आईएनटी, या एक बिगिनट हो सकता है - या कुछ भी वास्तव में - कोई फर्क नहीं पड़ता। प्वाइंट यह है: वह मान आपके स्वयं के, वास्तविक डेटा से संबंधित नहीं है - और सिस्टम आपके लिए यह मान स्वचालित रूप से उत्पन्न कर रहा है। –

+0

@ मार्क-एस आपको लिखने के लिए समय निकालने के लिए धन्यवाद। आपके उत्तर ने सही अर्थ बनाया। – HPWD

4

मेरे टिप्पणी # 3 बात करने के लिए मुख्य रूप से संदर्भ में है? यहां एक मामला है।

मैं एक प्रतिकृति परिदृश्य से निपट रहा हूं जिसमें एकाधिक उपग्रह डेटाबेस को मास्टर के साथ विलय करने की आवश्यकता है। प्रत्येक उपग्रह एक ही टेबल पर डेटा उत्पन्न कर रहा है, इसलिए मास्टर को टेबलों के विलय से विशिष्टता बाधा का उल्लंघन होता है। मैं एक समाधान के हिस्से के रूप में अद्यतन कैस्केड पर उपयोग करने की कोशिश कर रहा हूं जिसमें प्रत्येक विलय के दौरान मैं कुंजी को फिर से बढ़ाता हूं। अद्यतन कैस्केड पर प्रक्रिया के हिस्से को स्वचालित करके इस प्रक्रिया को सरल बनाना चाहिए।

11

कुछ दिन पहले मुझे ट्रिगर के साथ कोई समस्या हुई थी, और मुझे पता चला है कि ON UPDATE CASCADE उपयोगी हो सकता है। इस उदाहरण (PostgreSQL) पर एक नज़र डालें:

CREATE TABLE club 
(
    key SERIAL PRIMARY KEY, 
    name TEXT UNIQUE 
); 

CREATE TABLE band 
(
    key SERIAL PRIMARY KEY, 
    name TEXT UNIQUE 
); 

CREATE TABLE concert 
(
    key SERIAL PRIMARY KEY, 
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE, 
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE, 
    concert_date DATE 
); 

मेरी अंक में मैं संगीत कार्यक्रम की मेज को अद्यतन करने के लिए कुछ अतिरिक्त परिचालन (ट्रिगर) को परिभाषित करने के लिए किया था। उन परिचालनों को club_name और band_name को संशोधित करना था। मैं संदर्भ के कारण, ऐसा करने में असमर्थ था। मैं संगीत कार्यक्रम को संशोधित नहीं कर सका और फिर क्लब और बैंड टेबल से निपट सकता था। मैं इसे दूसरी तरफ भी नहीं कर सका। ON UPDATE CASCADE समस्या को हल करने की कुंजी थी।

+2

अच्छी टिप्पणी। मुझे अपडेट कैस्केड भी उपयोगी लगता है, किसी भी मामले में आपको अपना आईडी बदलना होगा। मैं दूसरों से भी सहमत हूं कि यह परिवर्तन इतना विशिष्ट नहीं होना चाहिए। उदाहरण के लिए, यदि आप उद्धरण देते हैं, तो मुझे लगता है कि डेटा की बड़ी मात्रा में, संभवतः टेक्स्ट फ़ील्ड का उपयोग करके विदेशी कुंजी से संबंधित डेटाबेस डेटाबेस का सबसे तेज़ प्रदर्शन नहीं हो सकता है। ध्यान दें, कि यदि कॉन्सर्ट टेबल में विदेशी संबंध क्लब का उपयोग करता है। सीरियल और बैंड। सर्कल, नाम में परिवर्तन टेबल के बीच संबंध को प्रभावित नहीं करेंगे। हालांकि, मुझे लगता है कि आपातकालीन समस्याओं को हल करने के लिए अद्यतन कैस्केड एक बेहतरीन उपकरण है। सादर –

+3

यह एक संदिग्ध डिज़ाइन है जो यद्यपि एक विपरीत उदाहरण के लिए बनाता है। यदि आप प्रत्येक तालिका की प्राथमिक कुंजी के बजाय 'नाम' का संदर्भ देते हैं तो 'क्लब' और 'बैंड' में प्राथमिक कुंजी के रूप में दो 'सेरियल' कॉलम रखने का क्या मतलब है? –

3

यह एक उत्कृष्ट सवाल है, मेरे पास कल भी यही सवाल था। मैंने इस समस्या के बारे में सोचा, विशेष रूप से "अद्यतन अद्यतन कैस्केड" जैसे कुछ अस्तित्व में खोजे और सौभाग्य से एसक्यूएल के डिजाइनरों ने इसके बारे में भी सोचा था। मैं टेड.स्ट्रास से सहमत हूं, और मैंने नोरन के मामले पर भी टिप्पणी की।

मैंने इसका उपयोग कब किया? टेड की तरह, जब आप एक समय में कई डेटाबेस का इलाज कर रहे हैं, और उनमें से एक में संशोधन, एक तालिका में, टेड को "उपग्रह डेटाबेस" कहने में किसी भी प्रकार का प्रजनन होता है, जिसे मूल के साथ नहीं रखा जा सकता आईडी, और किसी भी कारण से आपको एक नया निर्माण करना होगा, यदि आप पुराने पर डेटा अपडेट नहीं कर सकते हैं (उदाहरण के लिए अनुमतियों के कारण, या यदि आप ऐसे मामले में फास्टनेस की खोज कर रहे हैं जो इतनी अस्थिर है एक बहुत ही कम रहता उपयोगिता सामान्यीकरण की कुल नियमों के लिए पूर्ण और बोलना सम्मान के पात्र हैं नहीं है, बस क्योंकि हो जाएगा)

तो, मैं दो अंक में इस बात से सहमत:

(ए) हाँ, में कई बार एक बेहतर डिजाइन इससे बच सकता है; लेकिन

(बी।) माइग्रेशन के मामलों में, डेटाबेस को दोहराना, या आपात स्थिति को हल करना, यह एक महान उपकरण है जो सौभाग्य से वहां था जब मैं खोज करने के लिए गया था।

संबंधित मुद्दे