वास्तव में या भौतिक रूप से रिकॉर्ड को हटाने के विपरीत एक रिकॉर्ड की तार्किक / सॉफ्ट डिलीट (यानी रिकॉर्ड को हटाए गए ध्वज को सेट करना) का फायदा क्या है?
क्या यह आम बात है?
क्या यह सुरक्षित है?
वास्तव में या भौतिक रूप से रिकॉर्ड को हटाने के विपरीत एक रिकॉर्ड की तार्किक / सॉफ्ट डिलीट (यानी रिकॉर्ड को हटाए गए ध्वज को सेट करना) का फायदा क्या है?
क्या यह आम बात है?
क्या यह सुरक्षित है?
जवाबों:
लाभ यह है कि आप इतिहास (ऑडिटिंग के लिए अच्छा) रखते हैं और आपको डेटाबेस में विभिन्न अन्य तालिकाओं के माध्यम से एक डिलीट को कैस्केडिंग करने के बारे में चिंता करने की ज़रूरत नहीं है जो उस पंक्ति को संदर्भित करते हैं जिसे आप हटा रहे हैं। नुकसान यह है कि आपको ध्वज को ध्यान में रखने के लिए किसी भी रिपोर्टिंग / प्रदर्शन विधियों को कोड करना होगा।
जहाँ तक अगर यह एक आम बात है - मैं कहूँगा हाँ, लेकिन किसी भी चीज़ के साथ चाहे आप इसका उपयोग करें यह आपके व्यवसाय की जरूरतों पर निर्भर करता है।
EDIT: एक और नुकसान का विचार - यदि आपके पास टेबल पर अद्वितीय अनुक्रमित हैं, तो हटाए गए रिकॉर्ड अभी भी "एक" रिकॉर्ड लेंगे, इसलिए आपको उस संभावना के आसपास भी कोड करना होगा (उदाहरण के लिए, एक उपयोगकर्ता तालिका जिसमें एक अद्वितीय सूचकांक है उपयोगकर्ता नाम। एक हटाए गए रिकॉर्ड को हटाए गए उपयोगकर्ता नाम को नए रिकॉर्ड के लिए फिर भी अवरुद्ध किया जाएगा। इसके आसपास काम करने से आप हटाए गए उपयोगकर्ता नाम कॉलम पर एक GUID से निपट सकते हैं, लेकिन यह बहुत ही हैकई वर्कअराउंड है जो मैं सुझा नहीं सकता। शायद उस परिस्थिति में यह संभव नहीं है। केवल एक नियम के लिए बेहतर होगा कि एक बार उपयोगकर्ता नाम का उपयोग करने के बाद, इसे कभी भी प्रतिस्थापित नहीं किया जा सकता है।)
CREATE UNIQUE INDEX ... WHERE DELETED_AT is null
(PostgreSQL में) और फिर किसी भी विलोपन तिथि वाली सभी पंक्तियों को अनुक्रमित नहीं किया जाता है। (उन्हें इसके बजाय एक गैर-अनूठे सूचकांक में शामिल किया जा सकता है।)
क्या लॉजिकल रीजनिंग कॉमन प्रैक्टिस है? हां मैंने इसे कई जगहों पर देखा है। क्या वे सुरक्षित हैं? यह वास्तव में निर्भर करता है कि क्या वे किसी भी कम सुरक्षित हैं तो डेटा को हटाने से पहले?
जब मैं एक टेक लीड था, मैंने मांग की थी कि हमारी टीम डेटा के हर टुकड़े को रखे, मुझे उस समय पता था कि हम विभिन्न बीआई अनुप्रयोगों के निर्माण के लिए उस सभी डेटा का उपयोग करेंगे, हालांकि उस समय हमें नहीं पता था कि क्या आवश्यकताएं हैं हो। हालांकि यह ऑडिटिंग, समस्या निवारण और रिपोर्टिंग के दृष्टिकोण से अच्छा था (यह बी 2 बी लेनदेन के लिए एक ई-कॉमर्स / टूल साइट था, और यदि कोई व्यक्ति किसी उपकरण का उपयोग करता है, तो हम इसे रिकॉर्ड करना चाहते थे, भले ही उनका खाता बाद में बंद हो गया हो), इसमें कई डाउनसाइड थे।
डाउनसाइड्स में शामिल हैं (पहले से उल्लिखित अन्य शामिल नहीं):
तार्किक, भौतिक विलोपन या संग्रह करने का निर्णय लेते समय मैं खुद से ये प्रश्न पूछूंगा:
Activated
तालिका और Deactivated
तालिका स्कीमा - Id,Name,etc..
पंक्ति में Activated
- 1001,Smith007,etc...
जब वह निष्क्रिय हो जाता है, तो हम smith के लिए सभी लेकिन ID कॉलम को साफ कर सकते हैं Activated
और उसे उसमें जोड़ सकते हैं Deactivated
।
थोड़ी देर हो सकती है, लेकिन मैं सभी को सुझाव देता हूं कि वे तार्किक / सॉफ्ट डिलीट के बारे में पिनाल डेव के ब्लॉग पोस्ट की जाँच करें :
मुझे इस तरह का डिज़ाइन पसंद नहीं है [सॉफ्ट डिलीट]। मैं आर्किटेक्चर का दृढ़ विश्वास हूं जहां केवल आवश्यक डेटा एकल तालिका में होना चाहिए और बेकार डेटा को एक संग्रहीत तालिका में स्थानांतरित किया जाना चाहिए। आइलेटेड कॉलम का अनुसरण करने के बजाय, मैं दो अलग-अलग तालिकाओं के उपयोग का सुझाव देता हूं: एक आदेश के साथ और दूसरा हटाए गए आदेशों के साथ। उस स्थिति में, आपको दोनों तालिका को बनाए रखना होगा, लेकिन वास्तव में, इसे बनाए रखना बहुत आसान है। जब आप isDleted कॉलम में UPDATE स्टेटमेंट लिखते हैं, तो INSERT INTO को एक अन्य तालिका लिखें और इसे मूल तालिका से हटाएं। यदि स्थिति रोलबैक की है, तो रिवर्स ऑर्डर में एक और INSERT INTO और DELETE लिखें। यदि आप एक असफल लेनदेन के बारे में चिंतित हैं, तो इस कोड को ट्रांज़ेक्शन में लपेटें।
उपरोक्त वर्णित स्थितियों में छोटी तालिका छंद बड़ी तालिका के फायदे क्या हैं?
- एक छोटी सी मेज को बनाए रखना आसान है
- अनुक्रमणिका पुनर्निर्माण कार्य बहुत तेज हैं
- संग्रह डेटा को किसी अन्य फ़ाइल समूह में ले जाने से प्राथमिक फ़ाइल समूह का भार कम हो जाएगा (यह विचार करते हुए कि सभी फ़ाइल समूह अलग-अलग सिस्टम पर हैं) - इससे बैकअप की गति भी बढ़ेगी।
- छोटे आकार के कारण आंकड़े अक्सर अपडेट किए जाएंगे और यह कम संसाधन गहन होगा।
- सूचकांक का आकार छोटा होगा
- तालिका का प्रदर्शन छोटे तालिका आकार के साथ बेहतर होगा।
मैं एक NoSQL डेवलपर हूं, और अपनी आखिरी नौकरी पर, मैंने ऐसे डेटा के साथ काम किया, जो किसी के लिए हमेशा महत्वपूर्ण था, और अगर यह उसी दिन दुर्घटना से हटा दिया गया था, तो मैं इसे अंतिम बैकअप में नहीं ढूंढ सका था कल से! उस स्थिति में, नरम विलोपन ने हमेशा दिन बचाया।
मैंने टाइमस्टैम्प का उपयोग करके सॉफ्ट-डिलीट किया, उस तारीख को पंजीकृत करना जब दस्तावेज़ को हटा दिया गया था:
IsDeleted = 20150310 //yyyyMMdd
हर रविवार, एक प्रक्रिया डेटाबेस पर चलती थी और IsDeleted
क्षेत्र की जाँच करती थी । यदि वर्तमान तिथि और टाइमस्टैम्प के बीच का अंतर N दिनों से अधिक था, तो दस्तावेज़ को हटा दिया गया था। दस्तावेज़ को ध्यान में रखते हुए अभी भी कुछ बैकअप पर उपलब्ध है, यह करना सुरक्षित था।
EDIT: यह NoSQL उपयोग मामला डेटाबेस में बनाए गए बड़े दस्तावेजों के बारे में है, दसियों या उनमें से हर दिन सैकड़ों, लेकिन हजारों या लाखों नहीं। सामान्य तौर पर, वे वर्कफ़्लो प्रक्रियाओं की स्थिति, डेटा और अनुलग्नकों के साथ दस्तावेज़ थे। यही कारण था कि उपयोगकर्ता द्वारा किसी महत्वपूर्ण दस्तावेज़ को हटाने की संभावना थी। यह उपयोगकर्ता किसी व्यक्ति के विशेषाधिकारों या शायद दस्तावेज़ के स्वामी के साथ हो सकता है, बस कुछ का नाम लेने के लिए।
TL; DR मेरा उपयोग मामला बड़ा डेटा नहीं था। उस मामले में, आपको एक अलग दृष्टिकोण की आवश्यकता होगी।
मैंने जो एक पैटर्न का उपयोग किया है वह दर्पण तालिका बनाने और प्राथमिक तालिका पर एक ट्रिगर संलग्न करने के लिए है, इसलिए दर्पण तालिका में सभी हटाए गए (और अपडेट यदि वांछित हैं) दर्ज किए गए हैं।
यह आपको हटाए गए / परिवर्तित रिकॉर्ड को "पुनर्निर्माण" करने की अनुमति देता है, और आप अभी भी प्राथमिक तालिका में हार्ड डिलीट कर सकते हैं और इसे "साफ" रख सकते हैं - यह "पूर्ववत" फ़ंक्शन के निर्माण की भी अनुमति देता है, और आप तिथि, समय भी रिकॉर्ड कर सकते हैं , और उपयोगकर्ता जिन्होंने मिरर टेबल में कार्रवाई की (चुड़ैल शिकार स्थितियों में अमूल्य)।
अन्य फायदा यह है कि प्राथमिक रूप से क्वेरी करते समय गलती से हटाए गए रिकॉर्ड सहित कोई मौका नहीं है जब तक कि आप जानबूझकर मिरर टेबल से रिकॉर्ड सहित परेशानी की ओर नहीं जाते हैं (आप लाइव और हटाए गए रिकॉर्ड दिखाना चाह सकते हैं)।
एक और लाभ यह है कि दर्पण तालिका को स्वतंत्र रूप से शुद्ध किया जा सकता है, क्योंकि इसमें कोई वास्तविक विदेशी कुंजी संदर्भ नहीं होना चाहिए, यह एक प्राथमिक तालिका से शुद्ध करने की तुलना में अपेक्षाकृत सरल ऑपरेशन बनाता है जो सॉफ्ट डिलीट का उपयोग करता है लेकिन फिर भी अन्य तालिकाओं के लिए संदर्भात्मक कनेक्शन है।
और क्या फायदे? - अगर आपके पास प्रोजेक्ट पर काम करने वाले कोडर्स का एक गुच्छा है, तो डेटाबेस पर मिश्रित कौशल और विस्तार स्तरों पर ध्यान देने के साथ पढ़ता है, तो आपको रातों को रहने की उम्मीद नहीं है कि उनमें से एक को हटाना शामिल नहीं करना भूल गया रिकॉर्ड्स (योग्य, शामिल नहीं किए गए रिकॉर्ड्स = ट्रू), जिसके परिणामस्वरूप ओवरस्टेटिंग जैसी चीजें होती हैं, जो कहती हैं कि ग्राहकों को उपलब्ध नकदी की स्थिति, जिसके बाद वे कुछ शेयर खरीदते हैं (जैसे, एक ट्रेडिंग सिस्टम में), जब आप ट्रेडिंग सिस्टम के साथ काम करते हैं, तो आप भले ही वे थोड़ा और अधिक प्रारंभिक "ओवरहेड" हो सकते हैं, भले ही मजबूत समाधान के मूल्य का पता लगा लेंगे।
अपवाद:
- एक गाइड के रूप में, "संदर्भ" डेटा जैसे कि उपयोगकर्ता, श्रेणी, आदि के लिए सॉफ्ट डिलीट का उपयोग करें, और "तथ्य" प्रकार के डेटा के लिए मिरर टेबल पर हार्ड डिलीट करता है, अर्थात, लेन-देन इतिहास।
मैं आमतौर पर तार्किक विलोपन का उपयोग करता हूं - मुझे लगता है कि वे तब अच्छी तरह से काम करते हैं जब आप एक संग्रहित तालिका (जिसे खोजा जा सकता है, यदि आवश्यक हो तो 'डिलीट' किए गए डेटा को भी बंद कर सकते हैं) और इस तरह एप्लिकेशन के प्रदर्शन को प्रभावित करने का कोई मौका नहीं मिलता है।
यह अच्छी तरह से काम करता है क्योंकि आपके पास अभी भी डेटा है अगर आप कभी भी ऑडिट किए जाते हैं यदि आप इसे भौतिक रूप से हटाते हैं, तो यह चला गया है !
मैं विशेष रूप से व्यावसायिक एप्लिकेशन की एक पंक्ति के लिए, या उपयोगकर्ता खातों के संदर्भ में तार्किक डिलीट का बहुत बड़ा प्रशंसक हूं। मेरे कारण सरल हैं: कई बार मैं नहीं चाहता कि कोई उपयोगकर्ता अब सिस्टम का उपयोग कर सके (इसलिए खाते को हटाए गए के रूप में चिह्नित किया गया है), लेकिन यदि हमने उपयोगकर्ता को हटा दिया है, तो हम उनके सभी काम खो देंगे और ऐसे।
एक अन्य आम परिदृश्य यह है कि उपयोगकर्ता डिलीट होने के कुछ समय बाद फिर से तैयार हो सकते हैं। यह उपयोगकर्ता के लिए अपने सभी डेटा को मौजूद होने के लिए एक बहुत अच्छा अनुभव है क्योंकि इसे हटाने से पहले इसे हटा दिया गया था।
मैं आमतौर पर उपयोगकर्ताओं को अनिश्चित काल के लिए "निलंबित" करने के रूप में अधिक हटाने के बारे में सोचता हूं। आपको कभी नहीं पता कि उन्हें कब वैध रूप से वापस आने की आवश्यकता होगी।
मैं लगभग हमेशा नरम हटाता हूँ और यहाँ क्यों:
isdeleted
हर जगह चेक करना कोई समस्या नहीं है, आपको userid
वैसे भी जांच करना होगा (यदि डेटाबेस में कई उपयोगकर्ताओं का डेटा है)। आप कोड को चेक को लागू कर सकते हैं, उन दो चेक को एक अलग फ़ंक्शन पर रख सकते हैं (या विचारों का उपयोग कर सकते हैं)पुन: "क्या यह सुरक्षित है?" - जो आपके मतलब पर निर्भर करता है।
अगर आपका मतलब है कि भौतिक डिलीट करने से, आप किसी को हटाए गए डेटा को खोजने से रोकेंगे , तो हाँ, यह कम या ज्यादा सच है; आप उन संवेदनशील डेटा को भौतिक रूप से हटाने के लिए सुरक्षित हैं जिन्हें मिटाने की आवश्यकता है, क्योंकि इसका मतलब है कि यह स्थायी रूप से डेटाबेस से चला गया है। (हालांकि, महसूस करें कि प्रश्न में डेटा की अन्य प्रतियां हो सकती हैं, जैसे कि बैकअप में, या लेन-देन लॉग, या पारगमन से रिकॉर्ड किया गया संस्करण, उदाहरण के लिए एक पैकेट स्निफर - सिर्फ इसलिए कि आप अपने डेटाबेस से नहीं हटाते हैं गारंटी है कि इसे कहीं और नहीं बचाया गया था।)
यदि आपका मतलब है कि लॉजिकल डिलीट करने से, आपका डेटा अधिक सुरक्षित है क्योंकि आप कभी भी कोई डेटा नहीं खोएंगे , यह भी सच है। यह ऑडिट परिदृश्यों के लिए अच्छा है; मैं इस तरह से डिजाइन करता हूं क्योंकि यह मूल तथ्य को स्वीकार करता है कि एक बार डेटा उत्पन्न होने के बाद, यह वास्तव में कभी नहीं चलेगा (विशेषकर अगर यह कभी इंटरनेट खोज इंजन द्वारा कैश्ड होने की क्षमता, कहे,)। बेशक, एक वास्तविक ऑडिट परिदृश्य के लिए यह आवश्यक है कि न केवल तार्किक को हटा दिया जाए, बल्कि उस अपडेट को भी लॉग किया जाए, जिसमें परिवर्तन के समय और बदलाव करने वाले अभिनेता के साथ।
यदि आपका मतलब है कि डेटा किसी ऐसे व्यक्ति के हाथ में नहीं आएगा, जो इसे देखने वाला नहीं है, तो यह पूरी तरह से आपके आवेदन और इसकी सुरक्षा संरचना पर निर्भर है। उस संबंध में, तार्किक हटाना आपके डेटाबेस में किसी भी चीज़ से अधिक या कम सुरक्षित नहीं है।
मैं तार्किक रूप से नष्ट होने से बहुत असहमत हूं क्योंकि आप कई त्रुटियों के संपर्क में हैं।
सबसे पहले प्रश्नों में, प्रत्येक क्वेरी को IsDeleted फ़ील्ड का ध्यान रखना चाहिए और जटिल प्रश्नों के साथ त्रुटि की संभावना अधिक हो जाती है।
दूसरा प्रदर्शन: केवल 3 सक्रिय के साथ 100000 आरईएस के साथ एक तालिका की कल्पना करें, अब अपने डेटाबेस की तालिकाओं के लिए इस संख्या को गुणा करें; एक और प्रदर्शन समस्या पुराने (हटाए गए रिकॉर्ड) के साथ नए रिकॉर्ड के साथ एक संभावित संघर्ष है।
एकमात्र लाभ जो मैं देख रहा हूं, वह रिकॉर्ड्स का इतिहास है, लेकिन इस परिणाम को प्राप्त करने के लिए अन्य तरीके हैं, उदाहरण के लिए आप एक लॉगिंग टेबल बना सकते हैं जहां आप जानकारी सहेज सकते हैं: इस फॉर्म में विवरण TableName,OldValues,NewValues,Date,User,[..]
कहां और *Values
क्या हो varchar
सकता है fieldname : value
; [..] या के रूप में जानकारी की दुकान xml
।
यह सब कोड या ट्रिगर के माध्यम से प्राप्त किया जा सकता है, लेकिन आप अपने पूरे इतिहास के साथ केवल एक टेबल हैं। एक अन्य विकल्प यह देखना है कि निर्दिष्ट डेटाबेस इंजन ट्रैकिंग परिवर्तन के लिए मूल समर्थन है, उदाहरण के लिए SQL सर्वर डेटाबेस पर SQL ट्रैक डेटा परिवर्तन हैं।
मैं पुराने रिकॉर्ड रखने के लिए सॉफ्ट-डिलीट करता था। मैंने महसूस किया कि उपयोगकर्ता पुराने रिकॉर्ड्स को देखने की जहमत नहीं उठाते, जितना मैंने सोचा था। यदि उपयोगकर्ता पुराने रिकॉर्ड देखना चाहते हैं, तो वे संग्रह या ऑडिट टेबल से देख सकते हैं, है ना? तो, सॉफ्ट-डिलीट का क्या फायदा? यह केवल अधिक जटिल क्वेरी स्टेटमेंट की ओर जाता है, आदि।
मेरे द्वारा कार्यान्वित नहीं किए जाने से पहले मैंने जो चीज़ें लागू की हैं, वे निम्नलिखित हैं:
ऑडिट लागू करना, सभी गतिविधियों को रिकॉर्ड करना (जोड़ना, संपादित करना, हटाना)। सुनिश्चित करें कि ऑडिट से जुड़ी कोई विदेशी कुंजी नहीं है, और सुनिश्चित करें कि यह तालिका सुरक्षित है और प्रशासकों को छोड़कर कोई भी नहीं हटा सकता है।
पहचान करें कि कौन सी तालिकाओं को "लेन-देन तालिका" माना जाता है, जो बहुत संभावना है कि इसे लंबे समय तक रखा जाएगा, और बहुत संभव है कि उपयोगकर्ता पिछले रिकॉर्ड या रिपोर्ट देखना चाहते हैं। उदाहरण के लिए; खरीद लेनदेन। इस तालिका को केवल मास्टर तालिका (जैसे कि विभाग-आईडी) के रूप में नहीं रखना चाहिए, बल्कि संदर्भ के रूप में नाम (जैसे कि विभाग-नाम), या रिपोर्टिंग के लिए किसी अन्य आवश्यक फ़ील्ड जैसी अतिरिक्त जानकारी भी रखें।
मास्टर टेबल के "सक्रिय / निष्क्रिय" या "सक्षम / अक्षम" या "छिपाने / दिखाने" रिकॉर्ड को लागू करें। इसलिए, रिकॉर्ड हटाने के बजाय, उपयोगकर्ता मास्टर रिकॉर्ड को अक्षम / निष्क्रिय कर सकता है। यह इस तरह से ज्यादा सुरक्षित है।
बस मेरी दो सेंट की राय है।
यदि संदर्भात्मक अखंडता पर कठोर हैं तो तार्किक विलोपन।
टेबल डेटा का एक अस्थायी पहलू होने पर (FROM_DATE - TO_DATE को मान्य हैं) करना सही है।
अन्यथा डेटा को ऑडिटिंग टेबल पर ले जाएं और रिकॉर्ड हटाएं।
सकारात्मक स्थिति की ओर:
यह रोलबैक करने का आसान तरीका है (यदि संभव हो तो)।
यह देखना आसान है कि समय में एक विशिष्ट बिंदु पर राज्य क्या था।
यह उन मामलों में काफी मानक है, जहां आप कुछ का इतिहास रखना चाहते हैं (उदाहरण के लिए @Jon Dewees उल्लेख के रूप में उपयोगकर्ता खाते)। और यह निश्चित रूप से एक महान विचार है अगर वहाँ उपयोगकर्ताओं को संयुक्त राष्ट्र को हटाने के लिए एक मजबूत मौका है।
यदि आप अपने प्रश्नों को हटाए जाने और आपके प्रश्नों को जटिल बनाने से हटाए गए रिकॉर्ड को फ़िल्टर करने के तर्क के बारे में चिंतित हैं, तो आप केवल उन विचारों का निर्माण कर सकते हैं जो आपके लिए फ़िल्टरिंग करते हैं और उसके विरुद्ध प्रश्नों का उपयोग करते हैं। यह समाधान और ऐसे रिपोर्टिंग में इन रिकॉर्ड के रिसाव को रोक देगा।
सिस्टम डिजाइन से परे आवश्यकताएं हैं जिनका उत्तर दिया जाना आवश्यक है। रिकॉर्ड प्रतिधारण में कानूनी या वैधानिक आवश्यकता क्या है? पंक्तियों से संबंधित क्या हैं, इसके आधार पर, एक कानूनी आवश्यकता हो सकती है कि डेटा को 'निलंबित' किए जाने के बाद एक निश्चित अवधि के लिए रखा जाए।
दूसरी ओर, आवश्यकता यह हो सकती है कि एक बार रिकॉर्ड 'डिलीट' हो जाने के बाद, यह वास्तव में और अपरिवर्तनीय रूप से हटा दिया गया हो। निर्णय लेने से पहले, अपने हितधारकों से बात करें।
वे डेटाबेस को प्रदर्शन नहीं करने देते क्योंकि इसमें कैसकेड की कार्यक्षमता को बेकार कर देना चाहिए।
सरल चीजों के लिए जैसे कि आवेषण, फिर से डालने के मामले में, फिर इसके पीछे का कोड दोगुना हो जाता है।
आप बस सीधे नहीं डाल सकते हैं, इसके बजाय आपको एक अस्तित्व की जांच करनी होगी और सम्मिलित करना होगा यदि यह पहले मौजूद नहीं है या हटाए गए ध्वज को अपडेट नहीं करता है यदि यह अन्य सभी कॉलमों को नए मूल्यों पर अपडेट करता है। इसे डेटाबेस ट्रांजेक्शन लॉग के अपडेट के रूप में देखा जाता है न कि गलत ऑडिट लॉग के कारण एक नया इंसर्ट।
वे प्रदर्शन समस्याओं का कारण बनते हैं क्योंकि तालिकाएँ अनावश्यक डेटा के साथ प्रभावित हो रही हैं। यह विशेष रूप से विशिष्टता के साथ अनुक्रमण के साथ कहर निभाता है।
मैं लॉजिकल डिलीट का बहुत बड़ा प्रशंसक नहीं हूं।
तोहिद की टिप्पणी का जवाब देने के लिए, हमें उसी समस्या का सामना करना पड़ा जहाँ हम रिकॉर्ड के इतिहास को बनाए रखना चाहते थे और यह भी सुनिश्चित नहीं था कि हम is_deleted
स्तंभ चाहते थे या नहीं।
मैं अपने अजगर के कार्यान्वयन और इसी तरह के उपयोग-मामले के बारे में बात कर रहा हूं जो हमने मारा।
हमने https://github.com/kvesteri/sqlalchemy-continuum का सामना किया जो आपकी संबंधित तालिका के लिए संस्करण तालिका प्राप्त करने का एक आसान तरीका है। कोड की न्यूनतम लाइनें और ऐड, डिलीट और अपडेट के लिए इतिहास कैप्चर करती हैं।
यह केवल is_deleted
कॉलम से अधिक कार्य करता है । इस प्रविष्टि के साथ क्या हुआ है, यह जांचने के लिए आप हमेशा वर्जन टेबल को पीछे कर सकते हैं। चाहे प्रविष्टि हटा दी गई हो, अपडेट की गई हो या जोड़ी गई हो।
इस तरह से हमें बिल्कुल भी is_deleted
कॉलम की आवश्यकता नहीं थी और हमारा डिलीट फंक्शन बहुत मामूली था। इस तरह हमें is_deleted=False
अपने किसी भी एप में चिन्हित करने की आवश्यकता नहीं है ।
सॉफ्ट डिलीट एक प्रोग्रामिंग प्रैक्टिस है, जो डेटा के अधिक प्रासंगिक होने पर अधिकांश एप्लिकेशन में अनुसरण की जाती है। वित्तीय अनुप्रयोग के एक मामले पर विचार करें, जहां अंतिम उपयोगकर्ता की गलती से एक डिलीट घातक हो सकता है। यही कारण है कि जब सॉफ्ट डिलीट प्रासंगिक हो जाता है। सॉफ्ट डिलीट में यूजर वास्तव में रिकॉर्ड से डेटा को डिलीट नहीं कर रहा है, बल्कि इसे आइडलेट के रूप में सच (सामान्य कन्वेंशन द्वारा) चिह्नित किया जा रहा है।
EF में 6.x या EF 7 आगे की ओर Softdelete को एक विशेषता के रूप में जोड़ा गया है, लेकिन हमें अभी के समय के लिए एक कस्टम विशेषता बनानी होगी।
मैं एक सॉफ्टवेर की सिफारिश करता हूं, एक डेटाबेस डिजाइन में और प्रोग्रामिंग प्रैक्टिस के लिए एक अच्छा सम्मेलन।
ज्यादातर समय सॉफटेलीटिंग का उपयोग किया जाता है क्योंकि आप कुछ डेटा को उजागर नहीं करना चाहते हैं, लेकिन आपको इसे ऐतिहासिक कारणों से रखना होगा (एक उत्पाद बंद हो सकता है, इसलिए आप इसके साथ कोई नया लेनदेन नहीं करना चाहते हैं लेकिन आपको अभी भी इसके साथ काम करने की आवश्यकता है बिक्री लेनदेन का इतिहास)। वैसे, कुछ इस बात से निपटने के लिए उत्पाद के संदर्भ के बजाय बिक्री लेनदेन डेटा में उत्पाद जानकारी मूल्य की प्रतिलिपि बना रहे हैं।
वास्तव में यह दृश्यमान / छिपी या सक्रिय / निष्क्रिय सुविधा के लिए एक रिकॉर्डिंग की तरह अधिक दिखता है। क्योंकि व्यापार की दुनिया में इसका अर्थ "हटाना" है। मैं यह कहना चाहूंगा कि टर्मिनेटर लोगों को हटा सकते हैं लेकिन बॉस सिर्फ उन्हें आग लगा सकते हैं।
यह अभ्यास बहुत ही सामान्य पैटर्न है और बहुत सारे कारणों के लिए बहुत सारे एप्लिकेशन द्वारा उपयोग किया जाता है। जैसा कि यह इसे प्राप्त करने का एकमात्र तरीका नहीं है, इसलिए आपके पास यह कहने वाले हजारों लोग होंगे कि यह महान या बकवास है और दोनों के पास बहुत अच्छे तर्क हैं।
सुरक्षा के दृष्टिकोण से, सॉफ्टडेइट ऑडिट की नौकरी को प्रतिस्थापित नहीं करेगा और यह बैकअप की नौकरी को भी प्रतिस्थापित नहीं करेगा। यदि आप "दो बैकअप केस के बीच इन्सर्ट / डिलीट" से डरते हैं, तो आपको फुल या बल्क रिकवरी मॉडल के बारे में पढ़ना चाहिए। मैं मानता हूं कि सॉफ्टएडली रिकवरी प्रक्रिया को अधिक तुच्छ बना सकता है।
अपनी आवश्यकता जानने के लिए आप तक।
एक विकल्प देने के लिए, हमारे पास MobiLink के माध्यम से अद्यतन करने वाले दूरस्थ उपकरणों का उपयोग करने वाले उपयोगकर्ता हैं। यदि हम सर्वर डेटाबेस में रिकॉर्ड हटाते हैं, तो वे रिकॉर्ड क्लाइंट डेटाबेस में कभी भी डिलीट नहीं होते हैं।
तो हम दोनों करते हैं। हम अपने ग्राहकों के साथ यह निर्धारित करने के लिए काम करते हैं कि वे कितने समय तक डेटा को पुनर्प्राप्त करने में सक्षम होना चाहते हैं। उदाहरण के लिए, आम तौर पर ग्राहक और उत्पाद तब तक सक्रिय रहते हैं जब तक कि हमारे ग्राहक का कहना है कि उन्हें हटा दिया जाना चाहिए, लेकिन बिक्री का इतिहास केवल 13 महीनों तक ही बरकरार रहता है और फिर स्वचालित रूप से हटा दिया जाता है। ग्राहक दो महीने के लिए हटाए गए ग्राहकों और उत्पादों को रखना चाहते हैं, लेकिन छह महीने तक इतिहास को बनाए रख सकते हैं।
इसलिए हम रातोंरात एक स्क्रिप्ट चलाते हैं जो इन मापदंडों के अनुसार तार्किक रूप से हटाई गई चीज़ों को चिह्नित करता है और फिर दो / छह महीने बाद, तार्किक रूप से हटाए गए कुछ भी चिह्नित किए गए आज हार्ड डिलीट हो जाएंगे।
हम एक स्मार्टफोन जैसे सीमित मेमोरी वाले क्लाइंट डिवाइस पर विशाल डेटाबेस होने के बजाय डेटा सुरक्षा के बारे में कम हैं। एक ग्राहक जो चार साल के लिए सप्ताह में दो बार 200 उत्पादों का ऑर्डर करता है, उसके पास 81,000 से अधिक इतिहास की लाइनें होंगी, जिनमें से 75% ग्राहक को परवाह नहीं है यदि वह देखता है।
यह सब सिस्टम और उसके डेटा के उपयोग के मामले पर निर्भर करता है।
उदाहरण के लिए, यदि आप एक सरकारी विनियमित प्रणाली (उदाहरण के लिए एक दवा कंपनी की एक प्रणाली जिसे गुणवत्ता प्रणाली का एक हिस्सा माना जाता है और इलेक्ट्रॉनिक रिकॉर्ड के लिए FDA के दिशानिर्देशों का पालन करना चाहिए) के बारे में बात कर रहे हैं, तो आपने अच्छी तरह से हिम्मत की है कि आप हार्ड डिलीट न करें! एफडीए से एक लेखा परीक्षक अंदर आ सकता है और उत्पाद संख्या एबीसी -123 से संबंधित प्रणाली के सभी रिकॉर्डों के लिए पूछ सकता है, और सभी डेटा बेहतर उपलब्ध होंगे। यदि आपके व्यवसाय प्रक्रिया के मालिक का कहना है कि सिस्टम किसी को भी आगे जाने वाले नए रिकॉर्ड पर उत्पाद संख्या ABC-123 का उपयोग करने की अनुमति नहीं देनी चाहिए, तो सिस्टम के भीतर इसे "निष्क्रिय" बनाने के बजाय सॉफ्ट-डिलीट विधि का उपयोग करें, जबकि अभी भी ऐतिहासिक डेटा को संरक्षित कर रहा है।
हालाँकि, हो सकता है कि आपके सिस्टम और उसके डेटा का उपयोग मामला हो जैसे "उत्तरी ध्रुव पर मौसम को ट्रैक करना"। शायद आप हर घंटे में एक बार तापमान रीडिंग लेते हैं, और दिन के अंत में एक दैनिक औसत एकत्र करते हैं। हो सकता है कि प्रति घंटा डेटा अब एकत्रीकरण के बाद उपयोग नहीं किया जाएगा, और आप एग्रीगेट बनाने के बाद प्रति घंटा रीडिंग को हार्ड-डिलीट कर देंगे। (यह एक बना-बनाया, तुच्छ उदाहरण है।)
मुद्दा यह है, यह सब सिस्टम और उसके डेटा के उपयोग के मामले पर निर्भर करता है, न कि एक तकनीकी दृष्टिकोण से शुद्ध रूप से किए जाने का निर्णय।
कुंआ! जैसा कि सभी ने कहा, यह स्थिति पर निर्भर करता है।
यदि आपके पास UserName या EmailID जैसे किसी स्तंभ पर कोई अनुक्रमणिका है - और आप कभी भी उसी उपयोगकर्ता नाम या EmailID के दोबारा उपयोग होने की उम्मीद नहीं करते हैं; आप सॉफ्ट डिलीट के साथ जा सकते हैं।
कहा कि, हमेशा जांचें कि क्या आपका चयन ऑपरेशन प्राथमिक कुंजी का उपयोग करता है। यदि आपका SELECT स्टेटमेंट एक प्राथमिक कुंजी का उपयोग करता है, तो WHERE क्लॉज के साथ एक ध्वज जोड़ने से बहुत अंतर नहीं पड़ेगा। आइए एक उदाहरण लेते हैं (छद्म):
तालिका उपयोगकर्ता (उपयोगकर्ता आईडी [प्राथमिक कुंजी], ईमेल, ईमेल हटाया गया)
SELECT * FROM Users where UserID = 123456 and IsDeleted = 0
उपयोगकर्ता क्वेरी कॉलम में प्राथमिक कुंजी होने के कारण यह क्वेरी प्रदर्शन के मामले में कोई अंतर नहीं करेगी। प्रारंभ में, यह PK पर आधारित तालिका को स्कैन करेगा और फिर अगली स्थिति निष्पादित करेगा।
ऐसे मामले जहां नरम हटाए गए काम नहीं कर सकते हैं:
प्रमुख रूप से सभी वेबसाइटों में साइन-अप आपकी अद्वितीय पहचान के रूप में ईमेलआईडी लेते हैं। हम बहुत अच्छी तरह से जानते हैं, एक बार फेसबुक, जी + जैसी वेबसाइट पर एक ईमेल का उपयोग किया जाता है, इसे किसी और द्वारा उपयोग नहीं किया जा सकता है।
एक दिन आता है जब उपयोगकर्ता वेबसाइट से अपनी प्रोफ़ाइल हटाना चाहता है। अब, यदि आप एक तार्किक हटाते हैं, तो वह उपयोगकर्ता कभी भी फिर से पंजीकरण करने में सक्षम नहीं होगा। इसके अलावा, एक ही ईमेल का उपयोग करके फिर से पंजीकरण करने का मतलब पूरे इतिहास को पुनर्स्थापित करना नहीं होगा। सभी जानते हैं, विलोपन का अर्थ है विलोपन। ऐसे परिदृश्यों में, हमें एक भौतिक हटाना होगा। लेकिन खाते के पूरे इतिहास को बनाए रखने के लिए, हमें हमेशा ऐसे अभिलेखों को संग्रह सारणी या हटाए गए तालिकाओं में संग्रहित करना चाहिए।
हां, उन परिस्थितियों में जहां हमारे पास बहुत सारी विदेशी टेबल हैं, हैंडलिंग काफी बोझिल है।
यह भी ध्यान रखें कि सॉफ्ट / लॉजिकल डिलीट से आपका टेबल साइज बढ़ेगा, इसलिए इंडेक्स साइज।
मैंने पहले ही एक अन्य पोस्ट में उत्तर दिया है । हालांकि, मुझे लगता है कि मेरा उत्तर यहां प्रश्न के अधिक फिट है।
नरम हटाने के लिए मेरे व्यावहारिक समाधान निम्नलिखित कॉलम के साथ एक नई तालिका बनाने के द्वारा संग्रह है:
original_id
,table_name
,payload
, (और एक वैकल्पिक प्राथमिक कुंजी `आईडी)।
original_id
हटाए गए रिकॉर्ड की मूल आईडी कहां है, हटाए गए रिकॉर्डtable_name
का टेबल नाम है ("user"
आपके मामले में),payload
हटाए गए रिकॉर्ड के सभी स्तंभों से JSON-stringized स्ट्रिंग है।मैं कॉलम पर एक इंडेक्स बनाने का भी सुझाव देता हूं
original_id
बाद के डेटा पुनः प्राप्त करने के लिए ।डेटा संग्रहीत करने के इस तरीके से। आपको होंगे ये फायदे
- इतिहास के सभी आंकड़ों पर नज़र रखें
- हटाए गए रिकॉर्ड की तालिका संरचना की परवाह किए बिना, किसी भी तालिका से अभिलेख संग्रह करने के लिए केवल एक ही स्थान है
- मूल तालिका में अद्वितीय सूचकांक की कोई चिंता नहीं
- मूल तालिका में विदेशी सूचकांक की जाँच की कोई चिंता नहीं है
WHERE
हटाने के लिए जाँच करने के लिए हर क्वेरी में कोई और अधिक खंड नहीं हैयहां पहले से ही एक चर्चा है जो बता रही है कि व्यवहार में नरम-विलोपन एक अच्छा विचार क्यों नहीं है। सॉफ्ट-डिलीट भविष्य में कुछ संभावित परेशानियों का परिचय देता है जैसे कि रिकॉर्ड की गिनती, ...
निगमन डेटा संरक्षण / अपराध है। नरम विलोपन के सांकेतिक रूप से तालिकाओं से डेटा को क्वेरी या पुनर्प्राप्त करते समय एक प्रदर्शन में कमी होगी। हमारे मामले में हम दोनों के संयोजन का उपयोग करते हैं: जैसा कि दूसरों ने पिछले उत्तरों में उल्लेख किया है, हम soft-delete
users/clients/customers
उदाहरण के लिए, और hard-delete
उन items/products/merchandise
तालिकाओं पर जहां डुप्लिकेट किए गए रिकॉर्ड हैं जिन्हें मधुमक्खी के काटने की आवश्यकता नहीं है।
यह मामले पर निर्भर करता है, नीचे पर विचार करें:
आमतौर पर, आपको रिकॉर्ड को "सॉफ्ट-डिलीट" करने की आवश्यकता नहीं है। इसे सरल और तेज रखें। जैसे उत्पाद को हटाना अब उपलब्ध नहीं है, इसलिए आपको यह जांचने की आवश्यकता नहीं है कि उत्पाद आपके ऐप (गणना, उत्पाद सूची, अनुशंसित उत्पाद इत्यादि) पर नरम-हटा नहीं है।
फिर भी, आप डेटा वेयरहाउस मॉडल में "सॉफ्ट-डिलीट" पर विचार कर सकते हैं। उदा। आप हटाए गए उत्पाद पर एक पुरानी रसीद देख रहे हैं। "