इस प्रश्न का ठीक से उत्तर देने के लिए आपको सबसे पहले यह तय करने की आवश्यकता है: इस प्रणाली / आवेदन के संदर्भ में "डिलीट" का क्या अर्थ है?
उस प्रश्न का उत्तर देने के लिए, आपको एक और प्रश्न का उत्तर देने की आवश्यकता है: रिकॉर्ड क्यों हटाए जा रहे हैं?
उपयोगकर्ता को डेटा को हटाने की आवश्यकता हो सकती है क्यों कई अच्छे कारण हैं। आमतौर पर मुझे पता चलता है कि वास्तव में एक कारण (प्रति तालिका) है कि क्यों एक हटाना आवश्यक हो सकता है। कुछ उदाहरण निम्न हैं:
- डिस्क स्थान को पुनः प्राप्त करने के लिए;
- प्रतिधारण / गोपनीयता नीति के अनुसार हार्ड-विलोपन;
- दूषित / निराशाजनक रूप से गलत डेटा, मरम्मत करने की तुलना में हटाना और पुन: उत्पन्न करना आसान है।
- बहुमत पंक्तियों की नष्ट हो जाती हैं, जैसे एक लॉग तालिका एक्स रिकॉर्ड करने के लिए सीमित / दिन।
हार्ड-विलोपन के कुछ बहुत खराब कारण भी हैं (बाद में इन कारणों पर अधिक):
- एक छोटी सी त्रुटि को ठीक करने के लिए। यह आमतौर पर डेवलपर आलस्य और एक प्रतिकूल यूआई को रेखांकित करता है।
- एक लेनदेन "शून्य" करने के लिए (उदाहरण के लिए चालान जिसे कभी भी बिल नहीं किया जाना चाहिए)।
- क्योंकि आप कर सकते हैं ।
क्यों, आप पूछते हैं, क्या यह वास्तव में इतनी बड़ी बात है? अच्छा OLE के साथ 'गलत क्या है DELETE
?
- किसी भी प्रणाली में पैसे के लिए दूर से बंधा हुआ, हार्ड-विलोपन सभी प्रकार की लेखांकन अपेक्षाओं का उल्लंघन करता है, भले ही संग्रह / कब्र की मेज पर ले जाया गया हो। इसे संभालने का सही तरीका एक पूर्वव्यापी घटना है ।
- पुरालेख तालिकाओं में लाइव स्कीमा से अलग होने की प्रवृत्ति है। यदि आप एक नए जोड़े गए कॉलम या कैसकेड के बारे में भूल जाते हैं, तो आप उस डेटा को स्थायी रूप से खो देते हैं।
- विशेष रूप से कैस्केड के साथ हार्ड विलोपन एक बहुत महंगा ऑपरेशन हो सकता है । लोगों का एक बहुत है कि व्यापक और अधिक से अधिक एक स्तर या कुछ मामलों में एहसास नहीं है ( किसी भी कैस्केडिंग, डीबीएमएस पर निर्भर करता है) के परिणामस्वरूप सेट-ऑपरेशन के बजाय रिकॉर्ड स्तर के ऑपरेशन होंगे।
- बार-बार, लगातार हार्ड विलोपन सूचकांक विखंडन की प्रक्रिया को गति देता है।
तो, मुलायम हटाना बेहतर है, है ना? नहीं वास्तव में नहीं:
- कैस्केड सेट करना बेहद मुश्किल हो जाता है। आप लगभग हमेशा ग्राहक को अनाथ पंक्तियों के रूप में दिखाई देते हैं।
- आपको केवल एक विलोपन ट्रैक करने के लिए मिलता है । क्या होगा यदि पंक्ति को हटा दिया जाए और कई बार हटाया नहीं जाए?
- प्रदर्शन पीडि़त पढ़ें, हालांकि यह विभाजन, विचारों और / या फ़िल्टर किए गए अनुक्रमित के साथ कुछ हद तक कम किया जा सकता है।
- जैसा कि पहले संकेत दिया गया था, यह वास्तव में कुछ परिदृश्यों / न्यायालयों में अवैध हो सकता है।
सच्चाई यह है कि ये दोनों दृष्टिकोण गलत हैं। हटाना गलत है। यदि आप वास्तव में यह सवाल पूछ रहे हैं तो इसका मतलब है कि आप लेनदेन के बजाय वर्तमान स्थिति को मॉडलिंग कर रहे हैं। यह डेटाबेस-भूमि में एक बुरा, बुरा अभ्यास है।
Udi Dahan ने इसके बारे में डोंट डिलीट - जस्ट डोन्ट में लिखा । नहीं है हमेशा किसी प्रकार का कार्य, लेन-देन, गतिविधि , या (मेरी पसंदीदा शब्द) घटना जो वास्तव में "हटाएँ" का प्रतिनिधित्व करता है। यदि आप बाद में प्रदर्शन के लिए "वर्तमान स्थिति" तालिका में अपभ्रंश करना चाहते हैं तो यह ठीक है, लेकिन ऐसा करें कि आपके द्वारा लेन-देन मॉडल को नीचे किए जाने के बाद , इससे पहले नहीं।
इस मामले में आपके पास "उपयोगकर्ता" हैं। उपयोगकर्ता अनिवार्य रूप से ग्राहक हैं। ग्राहकों का आपके साथ व्यावसायिक संबंध है। यह संबंध केवल पतली हवा में गायब नहीं होता है क्योंकि उन्होंने अपना खाता रद्द कर दिया है। वास्तव में क्या हो रहा है:
- ग्राहक खाता बनाता है
- ग्राहक खाता रद्द करता है
- ग्राहक खाता नवीनीकृत करता है
- ग्राहक खाता रद्द करता है
- ...
हर मामले में, यह एक ही ग्राहक है , और संभवतः एक ही खाता (यानी प्रत्येक खाता नवीनीकरण एक नया सेवा अनुबंध है)। तो आप पंक्तियों को क्यों हटा रहे हैं? यह मॉडल करना बहुत आसान है:
+-----------+ +-------------+ +-----------------+
| Account | --->* | Agreement | --->* | AgreementStatus |
+-----------+ +-------------+ +----------------+
| Id | | Id | | AgreementId |
| Name | | AccountId | | EffectiveDate |
| Email | | ... | | StatusCode |
+-----------+ +-------------+ +-----------------+
बस। यही सब है इसके लिए। आपको कभी भी कुछ भी हटाने की आवश्यकता नहीं है। उपरोक्त एक काफी सामान्य डिजाइन है जो लचीलेपन की एक अच्छी डिग्री को समायोजित करता है लेकिन आप इसे थोड़ा सरल कर सकते हैं; आप तय कर सकते हैं कि आपको "अनुबंध" स्तर की आवश्यकता नहीं है और बस "खाता" एक "खाता सूची" तालिका पर जाएं।
यदि आपके आवेदन में लगातार आवश्यकता को सक्रिय समझौतों / खातों की सूची प्राप्त करना है, तो यह एक (थोड़ा) मुश्किल क्वेरी है, लेकिन इसके लिए क्या विचार हैं:
CREATE VIEW ActiveAgreements AS
SELECT agg.Id, agg.AccountId, acc.Name, acc.Email, s.EffectiveDate, ...
FROM AgreementStatus s
INNER JOIN Agreement agg
ON agg.Id = s.AgreementId
INNER JOIN Account acc
ON acc.Id = agg.AccountId
WHERE s.StatusCode = 'ACTIVE'
AND NOT EXISTS
(
SELECT 1
FROM AgreementStatus so
WHERE so.AgreementId = s.AgreementId
AND so.EffectiveDate > s.EffectiveDate
)
और आपने कल लिया। अब आपके पास सॉफ्ट-डिलीट के सभी लाभों के साथ कुछ है लेकिन कमियां नहीं हैं:
- अनाथ रिकॉर्ड एक गैर-मुद्दा है क्योंकि सभी रिकॉर्ड हर समय दिखाई देते हैं; जब भी आवश्यक हो आप एक अलग दृष्टिकोण से चयन करें।
- "हटाना" आमतौर पर एक अविश्वसनीय रूप से सस्ता ऑपरेशन है - बस एक पंक्ति को एक घटना तालिका में सम्मिलित करना।
- किसी भी इतिहास को खोने का कोई मौका नहीं है, कभी भी , चाहे आप कितनी भी बुरी तरह से पंगा लें।
- यदि आपको जरूरत है (उदाहरण के लिए गोपनीयता कारणों से), तो आप अभी भी किसी खाते को हार्ड-डिलीट कर सकते हैं , और इस ज्ञान के साथ सहज रहें कि डिलीट साफ-सुथरा होगा और ऐप / डेटाबेस के किसी अन्य हिस्से के साथ हस्तक्षेप नहीं करेगा।
केवल समस्या से निपटने के लिए छोड़ा गया मुद्दा प्रदर्शन है। कई मामलों में यह वास्तव में गैर-इश्यू के कारण क्लस्टर इंडेक्स पर बदल जाता है AgreementStatus (AgreementId, EffectiveDate)
- वहां पर बहुत कम I / O मांग रहा है। लेकिन अगर यह कभी मुद्दा है, तो इसे हल करने के तरीके हैं, ट्रिगर्स, अनुक्रमित / भौतिक विचारों, एप्लिकेशन-स्तरीय घटनाओं आदि का उपयोग करना।
प्रदर्शन के बारे में बहुत जल्दी चिंता न करें - डिज़ाइन को सही तरीके से प्राप्त करना अधिक महत्वपूर्ण है, और इस मामले में "सही" का अर्थ है डेटाबेस का उपयोग करना जिस तरह से डेटाबेस का उपयोग किया जाना है, एक ट्रांजेक्शनल सिस्टम के रूप में।