क्या डेटाबेस तालिका में "रिकॉर्ड स्थिति" कॉलम रखना एक बुरा अभ्यास है?


12

मुझे पहले स्पष्ट करना होगा कि स्थिति स्तंभ तालिका में रिकॉर्ड (पंक्ति) द्वारा दर्शाए गए वास्तविक-विश्व आइटम की स्थिति को प्रतिबिंबित करने का इरादा नहीं है । बल्कि, यह रिकॉर्ड की स्थिति दिखाने का इरादा है।

यह ऐक्टिव / इनएक्टिव या क्लिष्ट जैसे जटिल हो सकता है जैसे एप्रूव्ड / डिलीट / लॉक / पेंडिंग / रिजेक्टेड इत्यादि। स्टेटस को बूलियन / शॉर्ट पूर्णांक कॉलम या सिंगल-कैरेक्टर कॉलम पर मैपिंग के साथ true/ 1= एक्टिव या एक्टिव किया जा सकता है। A= स्वीकृत है।

मूल विचार है कि एप्लिकेशन में रीसायकल बिन / ट्रैश-जैसे रिकवरी समर्थन होना चाहिए (और इसे डेटाबेस में अनुकरण करें)। यदि कोई फ्रंट-एंड GUI या अन्य इंटरफ़ेस है जो उपयोगकर्ता को "डिलीट" रिकॉर्ड करने दे सकता है, तो यह वास्तव में टेबल में रिकॉर्ड को डिलीट नहीं करता है, लेकिन बस रिकॉर्ड स्टेटस को Inactive या डिलीट कर देता है। जब इंटरफ़ेस रिकॉर्ड प्राप्त करता है, तो यह हमेशा रिकॉर्ड प्राप्त करता है जो केवल इस स्थिति से मेल खाता है कि स्थिति सक्रिय या स्वीकृत है।

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

मेरे सवाल:

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

नोट: मैंने एक अलग इतिहास तालिका बनाए रखने के बारे में पढ़ा है लेकिन यह भंडारण के मामले में बदतर है और इससे ट्रिगर्स उत्पन्न होते हैं और ट्रिगर्स को ट्रैक की गई तालिका स्कीमा के साथ अद्यतित रखा जाता है।


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

जवाबों:


5

मैं इसे "सॉफ्ट डिलीट" के रूप में जानता हूं; रिकॉर्ड को "हटा दिया गया" के रूप में चिह्नित करना, भले ही यह वास्तव में नहीं है।

यह एक अच्छा अभ्यास है, या एक बुरा अभ्यास है?

निर्भर करता है।
यदि यह कुछ ऐसा है जिसे आपके उपयोगकर्ताओं को [बहुत] की आवश्यकता है तो यह शायद एक अच्छी बात है। अधिकांश मामलों में, हालांकि, मैं तर्क दूंगा कि यह थोड़ा लाभ के लिए [बहुत] ओवरहेड जोड़ रहा है।

क्या यह डेटा के सामान्यीकरण को प्रभावित करता है?

नहीं, लेकिन यह उस डेटा की आपकी अनुक्रमण को प्रभावित करेगा।
सुनिश्चित करें कि आप अपने अनुक्रमित में "हटाए गए" कॉलम को शामिल करते हैं, ताकि ये पंक्तियां आपके प्रश्नों में जल्द से जल्द बाहर हो जाएं।

संभावित नुकसान क्या हैं?

आपका डेटा थोड़ा और जटिल हो जाता है। डेटा के पास कहीं भी जाने वाली हर चीज को इन अतिरिक्त, "वास्तव में नहीं" रिकॉर्ड के बारे में "जानना" पड़ता है। या, आपको उन तालिकाओं पर दृश्य बनाने होंगे जो इन पंक्तियों को बाहर करते हैं और इन विचारों का उपयोग करते हैं, कहते हैं, आपकी रिपोर्टिंग उपकरण की पसंद।

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

क्या समान लक्ष्य प्राप्त करने की कोई वैकल्पिक विधि है? (नोट देखें)

नहीं वास्तव में कोई नहीं।

आप डेटाबेस को केवल एक निश्चित स्थिति के लिए डेटा पर अद्वितीय अवरोधों को लागू कर सकते हैं (लेकिन अन्य स्थितियों के लिए किसी भी संख्या में डुप्लिकेट की अनुमति दें)?

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

विकल्प ट्रिगर्स का उपयोग करना है, प्रक्रियात्मक कोड के स्निपेट्स जो तालिकाओं के बीच संदर्भात्मक अखंडता को लागू करते हैं और वे सभी चतुर, सशर्त सामान करते हैं जिनकी आपको ज़रूरत है। यह आपके विशेष मामले के लिए अच्छा है, लेकिन घोषणात्मक आरआई के अधिकांश लाभ खिड़की से बाहर जाते हैं - आपकी तालिकाओं के बीच कोई [बाहरी] पता लगाने योग्य संबंध नहीं है; यह सब ट्रिगर में "छिपा" है।

डेटाबेस, "रीसायकल बिन" जैसी सुविधा या टेबल-ट्रैकिंग / रिकवरी मूल रूप से क्यों नहीं प्रदान करते हैं, इसलिए हम इंटरफेस को बिना चिंता के वास्तविक रिकॉर्ड को नष्ट करने दे सकते हैं?

वे क्यों करेंगे ?

ये डेटाबेस हैं, आखिर फाइल सिस्टम या स्प्रेडशीट नहीं।

वे क्या करते हैं, वे [कर सकते हैं] बहुत, बहुत अच्छी तरह से।

वे क्या नहीं करते हैं, वहाँ शायद के लिए ज्यादा मांग नहीं किया गया है।


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

9

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

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


ओरेकल फ्लैशबैक मैं जो चाहता हूं उसके लिए आदर्श समाधान है। बहुत बुरा यह Oracle स्वामित्व है।
ADTC

4

एमआरपी / ईआरपी सिस्टम में "हटाने के लिए ध्वजांकित" फ़ील्ड का उपयोग करना बहुत आम है।

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

इसके बजाय, इसे हटाने के लिए ध्वजांकित करके, आप रिकॉर्ड पर आशय का एक स्पष्ट मार्कर डालते हैं और बाद में एक निर्धारित कार्य रिकॉर्ड को हटा सकता है यदि यह पुष्टि करता है कि सभी संबंधित तालिकाएं अब इसे संदर्भित नहीं कर रही हैं।

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


3

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

(मुझे विश्वास नहीं है कि यह आपके लिए "इतिहास तालिका" से है, जो मुझे लगता है कि आपको बदलने से पहले किसी अन्य तालिका में बस संशोधित या हटाए गए रिकॉर्ड की प्रतिलिपि बनाने का मतलब है)


दिलचस्प अवधारणा। मैं इस बात पर गौर करूंगा कि इसे कैसे लागू किया जा सकता है।
ADTC

1

मैं इन उपयोग-मामलों के लिए अक्सर इस पैटर्न को देखता हूं और उपयोग करता हूं:

  • मेटाडेटा जहाँ आप केवल उन मूल्यों को प्रदर्शित करना चाहते हैं जो आज प्रभावी हैं। उदाहरण के लिए, एक ड्रॉप डाउन सूची में कार निर्माताओं की सूची से चुनने के लिए जहां ID, VALUE, ENABLED के लिए टेबल मान सक्षम हैं 1, 'Ford', 1 और 2, 'Edsel', 0, 3, 'Toyota' , 1 केवल फोर्ड और टोयोटा के विकल्प देता है
  • एक केस प्रबंधन प्रणाली के लिए जहां प्रतिमान यह है कि एक मामला एक समय में केवल एक राज्य में हो सकता है। इस मामले में टॉगल कॉलम को CURRENT कहा गया था जिसमें 0 या 1 के मान को चेक बाधाओं द्वारा लागू किया गया था। जैसे ही मामला एक राज्य से दूसरे में जाता है, एप्लिकेशन पुराने राज्य के CURRENT ध्वज को 0 पर अपडेट करता है और नया 1 को

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


1

यदि आप रिपोर्टिंग के लिए अपने डेटा का उपयोग करने की योजना बना रहे हैं, तो यह एक अच्छा अभ्यास है (किसी भी बड़े पर्याप्त एप्लिकेशन को रिपोर्ट करने की आवश्यकता होगी)।

अपने एप्लिकेशन को गति देने के लिए, आपको वास्तव में रिपोर्टिंग टूल को अपने डेटाबेस पर नहीं चलने देना चाहिए। जैसे कि आपको दूसरे डेटाबेस में कॉपी / सिंक करने की आवश्यकता होगी।

मैं recordStatusकेवल दो राज्यों ACTIVEया टाइमस्टैम्प के CANCELLEDसंयोजन में उपयोग करता हूं lastUpdatedOn। मैं recordStatusइसके बजाय उपयोग करता हूं statusजिसका आमतौर पर व्यावसायिक अर्थ होता है।

जब मैं एप्लिकेशन के साथ रिपोर्टिंग डेटाबेस को सिंक्रनाइज़ कर रहा हूं, तो मैं यह lastUpdatedOnजानने के लिए एक फ़िल्टर करता हूं कि मैं रिपोर्टिंग साइड में किन लोगों को बदलने जा रहा हूं।

रिपोर्टिंग पक्ष पर मेरे पास recordStatusया lastUpdatedOnफ़ील्ड नहीं होंगे क्योंकि यह आम तौर पर रिपोर्ट नहीं किया जाएगा। जैसे कि जब मुझे कोई CANCELLEDस्थिति दिखाई देती है तो मैं रिपोर्टिंग पक्ष से उस रिकॉर्ड को हटा देता हूं जिस तरह से यह केवल सक्रिय रिकॉर्ड होता है।

इसे अन्य प्रकार के स्टोरों जैसे कि अभिलेखागार या बैकअप में विस्तारित किया जा सकता है जहां लगभग पूर्ण सिंक्रनाइज़ेशन की आवश्यकता होती है। हालाँकि, रिपोर्टिंग अधिक सामान्य उद्देश्य है।

के अपने उदाहरण के नोट Approved, New, Pendingएक अच्छा विचार है कि के रूप में एक व्यापार यह अर्थ जहां यह समझ में व्यापार बुद्धिमान बनाता है के लिए एक ही जाना चाहिए है एक आम क्षेत्र के रूप में डाल करने के लिए नहीं है।

के रूप में बंद के लिए, का उपयोग करें versionNoजो आपके रिकॉर्ड के लिए एक आशावादी ताला प्रदान करता है।

इसके बजाय एक और विकल्प recordStatusहै recordActiveऔर इसे एक ऐसे स्टोर के रूप में संग्रहीत किया जाता है booleanजो कम जगह लेता है और कम अनुक्रमण करता है, लेकिन मुझे भविष्य की ज़रूरतों के बारे में चिंतित होना चाहिए कि आप आगे नहीं बढ़ सकते।

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