डेटाबेस में कैसे हटाए जाने चाहिए?


44

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


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

आप किस डेटाबेस का उपयोग कर रहे हैं?
इवान कैरोल

टेम्पोरल टेबल SQL सर्वर 2016 और इसके बाद के संस्करण के लिए एक सबसे अच्छा समाधान है।
समीर

जवाबों:


37

हाँ, मैं निश्चित रूप से दूसरे विकल्प के लिए जाऊंगा, लेकिन मैं एक और फ़ील्ड को एक दिनांक फ़ील्ड में जोड़ दूंगा।

तो आप जोड़ें:

delete       boolean
delete_date  timestamp

यह आपको अनिश्चित कार्रवाई के लिए समय देगा।

यदि समय एक घंटे से कम है, तो कोई भी हटाना रद्द कर सकता है।

हटाए गए प्रविष्टि को वास्तव में हटाने के लिए बस एक संग्रहीत प्रक्रिया बनाएं जो हर प्रविष्टि को हटाए गए सेट के साथ एक घंटे से अधिक सही और समय पर साफ करेगी और इसे एक क्रोन टैब के रूप में डाल देगा जो हर 24 घंटे में चलता है।

घंटा सिर्फ एक उदाहरण है।


वैकल्पिक रूप से, आपके पास एक और झंडा हो सकता है - cleanedया कुछ और - जो इंगित करता है कि इस रिकॉर्ड से जुड़े डेटा को ठीक से, व्यापक रूप से हटा दिया गया है। जब तक cleanedयह सच नहीं है, तब तक रिकॉर्ड को हटाया नहीं जा सकता है।
गौरव

14
यह सामान्य दृष्टिकोण है। मैं आमतौर पर बूलियन और टाइमस्टैम्प deleted_atदोनों के सिमेंट को पकड़े हुए एक क्षेत्र का उपयोग करता हूं । तो यह है संभाल मामला है और है , एक टाइमस्टैम्प संभाल मामले युक्त है और एक टाइमस्टैम्प होता है, तो आप एक बार, भंडारण और आवेदन तर्क बचत। deletedelete_datedeleted_atNULLdeleteFALSEdelete_dateNULLdeleted_atdeleteTRUEdelete_date
जूलियन

1
मुझे बूलियन और डेट फील्ड पसंद है। आप विलोपन तर्क को कैसे लागू करते हैं इसके आधार पर आपके पास एक अलग तालिका भी हो सकती है जो तारीख और रिकॉर्ड के लिए अद्वितीय कुंजी है जो "हटा दिया गया" था। संग्रहीत कार्यविधियाँ इसे आसान बनाती हैं। यह 1 बिट बनाम 8+ के लिए आवश्यक प्रति पंक्ति अतिरिक्त स्थान लेता है। आप स्रोत तालिका को छूने के बिना प्रति दिन विलोपन पर रिपोर्ट करने में भी सक्षम होंगे।
एंड्रयूज

नोट: हटाना MySQL में एक आरक्षित शब्द है।
जेसन रिकर्ड

याद रखें कि deletedजब आप नेन्स्डलेटेड पंक्तियों के लिए क्वेरी कर रहे हों तो आपके फ़ील्ड पर फ़िल्टर किया गया इंडेक्स प्रदर्शन को बेहतर कर सकता है
रॉस प्रेसर

21

हमारे अनुप्रयोगों में हम वास्तव में किसी भी उपयोगकर्ता के अनुरोध पर कुछ भी नहीं हटाते हैं (हमारे ग्राहक विनियमित वातावरण में हैं जहां कुछ भी हटाने से संभावित कानूनी मुद्दे पैदा हो सकते हैं)।

हम पुराने संस्करणों को एक अलग ऑडिट टेबल में रखते हैं (इसलिए टेबल के लिए some_table जहाँ एक टेबल भी है जिसे some_table_audit कहा जाता है) जो एक अतिरिक्त संस्करण पहचानकर्ता होने के अलावा समान है (एक टाइमस्टैम्प यदि आपका DB suports समय मानों को पर्याप्त रूप से मान देता है, तो पूर्णांक संस्करण संख्या या UUID जो एक सामान्य ऑडिट टेबल, या इसी तरह की एक विदेशी कुंजी है), और ट्रिगर द्वारा ऑडिट टेबल को स्वचालित रूप से अपडेट करें (इसलिए हमें सभी कोड बनाने की आवश्यकता नहीं है जो ऑडिट की आवश्यकता के रिकॉर्ड को अपडेट करता है)।

इस तरफ:

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

यदि पूर्णांक संस्करण संख्या के बजाय (या साथ ही) टाइमस्टैम्प का उपयोग कर रहे हैं, तो आप जरूरत पड़ने पर निर्धारित समय के बाद पुरानी प्रतियों को हटाने के लिए इसका उपयोग कर सकते हैं। लेकिन इन दिनों डिस्क स्पेस अपेक्षाकृत सस्ता है, इसलिए जब तक हमारे पास पुराने डेटा (यानी डेटा सुरक्षा नियमों को छोड़ने का कारण नहीं है, जो कहते हैं कि आपको एक्स / महीनों के बाद क्लाइंट डेटा को हटाना चाहिए) हम नहीं करेंगे।


यह उत्तर कुछ वर्षों के आसपास रहा है और कुछ प्रमुख बातें जो इस प्रकार की योजना को प्रभावित कर सकती हैं, तब से बदल गई हैं। मैं बड़े पैमाने पर विस्तार में नहीं जाऊंगा, लेकिन आज इसे पढ़ने वाले लोगों के लाभ के लिए:

  • SQL सर्वर 2016 ने "सिस्टम वर्जन टेम्पोरल टेबल" पेश किया, जो आपके लिए इस काम का एक बहुत कुछ करता है, और इसके अलावा कुछ अच्छी सिंथैटिक शुगर प्रदान की जाती है ताकि ऐतिहासिक प्रश्नों को बनाने और बनाए रखने में आसान हो, और वे स्कीमा परिवर्तनों के एक सबसेट को समन्वित करते हैं आधार और इतिहास तालिकाएँ। वे अपने गुहाओं के बिना नहीं हैं, लेकिन वे इस तरह के उद्देश्य के लिए एक शक्तिशाली उपकरण हैं। अन्य DB प्रणालियों में भी इसी तरह की सुविधाएँ उपलब्ध हैं।

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


आप स्तंभों के विलोपन और नामकरण से कैसे निपटते हैं? अशांत करने के लिए सब कुछ सेट करें?
Stijn

1
@Stijn: यह अक्सर नहीं होता है कि संरचनाओं को बदल दिया जाता है ताकि बहुत ऊपर न आए। Colunms आम तौर पर कभी नहीं हटाए जाते हैं जब वे उत्पादन में मौजूद होते हैं - अगर वे इस्तेमाल किया जा रहा है तो बस किसी भी बाधा को छोड़ दें जो उन्हें बेनिग नल रोक देगा (या "जादू मूल्य" का उपयोग करके बाधाओं से निपटने के लिए चूक जोड़ें, हालांकि यह अधिक गंदा है) और दूसरे कोड में उनका जिक्र करना बंद कर दें। नाम बदलने के लिए: नया जोड़ें, पुराने का उपयोग करना बंद करें और यदि आवश्यक हो तो पुराने से नए डेटा की प्रतिलिपि बनाएँ। यदि आप कॉलम का नाम बदलते हैं तो सुनिश्चित करें कि एक ही समय में आधार और ऑडिट टेबल दोनों में एक ही परिवर्तन किया जाता है।
डेविड स्पिललेट

9

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


7

मैं अलग टेबल के साथ जाऊंगा। रूबी ऑन रेल्स में एक acts_as_versionedप्लगइन है, जो मूल रूप _versionसे अपडेट करने से पहले पोस्टफ़िक्स के साथ एक पंक्ति को दूसरी तालिका में सहेजता है। जबकि आपको उस सटीक व्यवहार की आवश्यकता नहीं है, यह आपके मामले के लिए भी काम करना चाहिए (हटाने से पहले प्रतिलिपि)।

@Spredzy की तरह मैं भी एक delete_dateकॉलम जोड़ने की सलाह दूंगा जो कि प्रोग्राम को शुद्ध रूप से शुद्ध करने में सक्षम हो जो कि X घंटे / दिन या जो भी हो के बाद बहाल नहीं किया गया है।


4

इस मामले के लिए हम आंतरिक रूप से जिस समाधान का उपयोग करते हैं, वह वस्तु के कुछ विशिष्ट राज्यों के लिए कुछ कठोर कोडित मूल्यों के साथ एक स्थिति स्तंभ है: हटाए गए, सक्रिय, निष्क्रिय, खुले, बंद, अवरुद्ध - प्रत्येक स्थिति का उपयोग कुछ अर्थ के साथ होता है। Db के दृष्टिकोण से, हम वस्तुओं को नहीं हटाते हैं, हम सिर्फ स्थिति बदलते हैं और ऑब्जेक्ट तालिका में प्रत्येक परिवर्तन के लिए इतिहास रखते हैं।


3

जब आप कहते हैं कि "बाद वाले समाधान को 'हटाए गए' रिकॉर्ड को अनदेखा करने के लिए अतिरिक्त एप्लिकेशन लॉजिक की आवश्यकता होगी, तो सरल समाधान के लिए एक दृश्य है जो उन्हें फ़िल्टर करता है।


यह सिर्फ देखने की बात नहीं है। सेट पर किए जा रहे किसी भी ऑपरेशन को "हटाए गए" रिकॉर्ड को बाहर करना होगा।
अबी

2

स्प्रेडज़ी ने जो सुझाव दिया, उसके समान, हम अपने सभी अनुप्रयोगों में विलोपन के लिए टाइमस्टैम्प क्षेत्र का उपयोग करते हैं। बूलियन शानदार है, क्योंकि टाइमस्टैम्प का सेट इंगित करता है कि रिकॉर्ड हटा दिया गया है। इस तरह, हमारा पीडीओ हमेशा AND (deleted IS NULL OR deleted = 0)चुनिंदा कथनों में जोड़ता है, जब तक कि मॉडल स्पष्ट रूप से हटाए गए रिकॉर्ड शामिल नहीं करता।

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


0

आप वैकल्पिक रूप से उपयोगकर्ताओं (और डेवलपर्स) पर ओनस रख सकते हैं और 'क्या आप निश्चित हैं?', 'क्या आप निश्चित रूप से निश्चित हैं?' और 'क्या तुम बिल्कुल, अच्छी तरह से और वास्तव में निश्चित हो?' रिकॉर्ड हटाए जाने से पहले के प्रश्न। हल्के स्पष्ट लेकिन विचार करने लायक।


0

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

इसके अलावा, लिखी गई प्रत्येक क्वेरी को विशेष रूप से उन्हें बाहर करना पड़ता है और अनुक्रमित करने के लिए उन पर भी विचार करने की आवश्यकता होती है।

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

अगला, डिलीट इन्सर्ट-डिलीट हो जाता है। हटाई जाने वाली पहली पंक्ति को उसके 'हटाए गए' स्कीमा समकक्ष में डाला जाता है। मुख्य तालिका में प्रश्न की पंक्ति को हटाया जा सकता है। हालाँकि, अतिरिक्त तर्क लाइन के साथ कहीं और जोड़े जाने की आवश्यकता है। विदेशी प्रमुख उल्लंघनों को संभाला जा सकता है।

विदेशी चाबियों को ठीक से संभालना होगा। एक पंक्ति को तार्किक रूप से नष्ट करना बुरा है, लेकिन जिसके प्राथमिक / अद्वितीय में अन्य तालिकाओं में कॉलम हैं जो इसे संदर्भित करते हैं। यह वैसे भी नहीं होना चाहिए। एक नियमित नौकरी विधवा पंक्तियों को हटा सकती है (वे पंक्तियाँ जिनकी प्राथमिक कुंजी में विदेशी कुंजी की उपस्थिति के बावजूद अन्य तालिकाओं में कोई संदर्भ नहीं है। यह, हालांकि, व्यावसायिक तर्क है।

समग्र लाभ तालिका में मेटाडेटा की कमी और प्रदर्शन में सुधार लाता है। कॉलम 'डिलीटडैट' कहता है कि यह पंक्ति वास्तव में यहां नहीं होनी चाहिए, लेकिन सुविधा के लिए, हम इसे वहां छोड़ रहे हैं और SQL क्वेरी को इसे संभालने दें। यदि हटाए गए पंक्ति की एक प्रतिलिपि को 'हटाए गए' स्कीमा में रखा जाता है, तो गर्म डेटा के साथ मुख्य तालिका में गर्म डेटा का उच्च प्रतिशत होता है (यह मानते हुए कि यह समय पर फैशन में संग्रहीत है) और कम अनावश्यक मेटाडेटा कॉलम। सूचकांक और प्रश्नों को अब इस क्षेत्र पर विचार करने की आवश्यकता नहीं है। पंक्ति आकार जितना छोटा होगा, उतनी पंक्तियाँ एक पृष्ठ पर फिट की जा सकती हैं, जितना तेज़ SQL सर्वर काम कर सकता है।

मुख्य नुकसान ऑपरेशन का आकार है। अब एक के बजाय दो ऑपरेशन हैं और अतिरिक्त तर्क और त्रुटि से निपटने के लिए। यह एक एकल कॉलम को अपडेट करने की तुलना में अधिक लॉकिंग को जन्म दे सकता है अन्यथा ले जाएगा। लेन-देन लंबे समय तक मेज पर ताले रखता है और इसमें दो टेबल शामिल होते हैं। कम से कम मेरे अनुभव में उत्पादन डेटा हटाना, शायद ही कभी कुछ किया गया हो। अब भी, एक मुख्य टेबल में लगभग 100 मिलियन प्रविष्टियों में से 7.5% में 'DeletedDate' कॉलम में एक प्रविष्टि है।

प्रश्न के उत्तर के रूप में, आवेदन के बारे में पता होना चाहिए। बस इसे उल्टे क्रम में करने की आवश्यकता होगी: मुख्य तालिका में 'हटाए गए' स्कीमा से पंक्ति डालें और फिर 'हटाए गए स्कीमा' से पंक्ति हटाएं। त्रुटियों, विदेशी चाबियों और इस तरह की समस्याओं से बचने के लिए कुछ अतिरिक्त तर्क और त्रुटि से निपटने की आवश्यकता है।

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