2010-01-20 20 views
7

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

अब मैं सुझाव दिया है कि हम बस एक और अतिरिक्त स्तंभ "स्थिति" कहा जाता है, जो मान्य मान की जोड़ी के लिए होता है जोड़ना चाहिए: सक्रिय और नष्ट। इस तरह हम सामान्य (सक्रिय) और हटाई गई घटनाओं के बीच अंतर कर सकते हैं और वास्तव में सरल प्रश्न बना सकते हैं (स्थिति * से चुनें जहां स्थिति = 'सक्रिय')। हालांकि मेरे सहयोगी असहमत थे। उन्होंने बताया कि परवाह किए बिना तथ्य अभी सक्रिय घटनाओं और हटाए गए ईवेंट में एक ही जानकारी साझा की एक भावी आवश्यकताओं में (इस प्रकार वे एक ही तालिका में संग्रहीत किया जा सकता है) मेरे परिवर्तन और उदाहरण के लिए ग्राहक को नष्ट कर दिया घटना के बारे में कुछ अतिरिक्त जानकारी स्टोर करने के लिए की आवश्यकता होगी (हटाने की तारीख की तरह, जिसने इसे हटा दिया, उसने ऐसा क्यों किया - टिप्पणी की तरह)। उन्होंने कहा कि भविष्य में उन आवश्यकताओं को पूरा करने के लिए हमें EVENTS तालिका में अतिरिक्त कॉलम जोड़ना होगा जो हटाए गए ईवेंट के लिए विशिष्ट डेटा धारण करेगा, न कि सक्रिय घटनाओं के लिए। उन्होंने एक समाधान का प्रस्ताव दिया, जहां अतिरिक्त तालिका बनाई गई है (जैसे DELETED_EVENTS) EVENTS तालिका के समान स्कीमा के साथ। प्रत्येक हटाए गए ईवेंट को EVENTS तालिका से भौतिक हटा दिया जाएगा और DELETED_EVENTS तालिका में ले जाया जाएगा।

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

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

+0

आप इसे एक समुदाय विकी के रूप में फ़्लैग करने पर विचार कर सकते हैं - मुझे यकीन नहीं है कि आपको एक सही उत्तरदायी उत्तर मिलेगा। – Mayo

+0

यह एक अच्छा सवाल है और मैं दिखाए गए कुछ उत्तरों को देखने की उम्मीद कर रहा हूं। DELETED_EVENT तालिका में प्रतिलिपि करते समय आपकी तालिका से पंक्तियों को निकालने से आपको कुछ समस्याएं हो सकती हैं यदि आपके ईवेंट तालिका के लिए कोई संदर्भ हैं जो आपको ऐतिहासिक उद्देश्यों के लिए रखने की आवश्यकता है।आप या तो खतरनाक विदेशी कुंजी, या विदेशी कुंजी के साथ समाप्त हो जाएंगे जिसमें आप दोनों टेबलों के साथ संभावित रूप से शामिल हो सकते हैं। यह सुंदर नहीं लगता है। – rayd09

+0

मेरा जवाब उत्तर देने से क्यों हटा दिया गया था ?? – anthonyv

उत्तर

0

ठीक उसी तरह से हम इसे संभालने के तरीके को ठीक करते हैं।

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

फिर अतिरिक्त जानकारी के लिए जो आप कैप्चर करना चाहते हैं, के लिए, बस यह अतिरिक्त जानकारी तालिका की तरह एक अलग 'ऑडिट' में जाएगी। हमारे मामले में हम इस अतिरिक्त तालिका काफी सामान्य बना दिया है और यदि आप अन्य संस्थाओं को कैप्चर करना चाहते है यह अब किसी भी तालिका के लिए इस ऑडिट की जानकारी पकड़ कर सकते हैं ... यह कैसे काम करता नीचे देखें ...

Event 
EventId EventName ... Deleted 
1   Dinner   0 
2   Supper   1 
3   Lunch    0 
4   Lunch    1 

Audit 
AuditId EntityTypeId  EntityId ActionTypeId ActionDateTime ... etc 
1   1 (Event)  2 (EventId) 1 (Deleted)  2/1/2010 12:00:00 
1   1 (Event)  4 (EventId) 1 (Deleted)  3/1/2010 12:00:00 

(स्थान की तरह - जहां स्थान एक टेबल है) के रूप में अच्छी तरह से यह तो इस प्रकार दिखाई देगा ...

Audit 
AuditId EntityTypeId  EntityId ActionTypeId ActionDateTime ... etc 
1   1 (Event)  2 (EventId) 1 (Deleted)  1/1/2010 12:00:00 
1   1 (Event)  4 (EventId) 1 (Deleted)  2/1/2010 12:00:00 
1   2 (Event)  2 (LocationId) 1 (Deleted)  3/1/2010 12:00:00 
1   2 (Event)  8 (LocationId) 1 (Deleted)  4/1/2010 12:00:00 
1   2 (Event)  9 (LocationId) 1 (Deleted)  5/1/2010 12:00:00 

जब आप अतिरिक्त ऑडिट डेटा आप के बारे में अपनी काफी सरल बात कर रहे हैं बाहर निकलना चाहते हैं। क्वेरी इस

SELECT * 
FROM Event E 
     INNER JOIN Audit A 
      ON E.EventId = A.EntityId 
WHERE E.Deleted = 1 
     AND A.EntityTypeId = 1 -- Where 1 stands for events 

कुछ ऐसा दिखाई देगा इसके अलावा इस लेखा परीक्षा तालिका अन्य घटनाओं पर कब्जा कर सकते हैं और न सिर्फ हटाता है ... इस ActionTypeId स्तंभ का उपयोग के माध्यम से किया जाता है। फिलहाल इसमें केवल 1 है (जो हटा है), लेकिन आप दूसरों को भी प्राप्त कर सकते हैं।

आशा इस मदद करता है

संपादित करें:

इस के शीर्ष अगर हम मजबूत लेखा परीक्षा आवश्यकताओं है पर हम निम्न कार्य ... ऊपर के किसी भी परिवर्तन, लेकिन हम 'xyz_Audit' नामक एक दूसरी डेटाबेस बनाने के जो डेटाबेस में होने वाली प्रत्येक क्रिया के लिए पूर्व और पोस्ट को कैप्चर करता है। इस दूसरे डेटाबेस में पहले डेटाबेस (ऑडिट तालिका के बिना) के समान स्कीमा है, सिवाय इसके कि प्रत्येक तालिका में 2 अतिरिक्त कॉलम हैं।

पहला अतिरिक्त कॉलम प्रीपोस्टफ्लैग है और दूसरा कॉलम ऑडिटआईड है। इसलिए प्राथमिक कुंजी अब 3 कॉलम, 'xyzId', 'PrePostFlag' और 'AuditId' में जाती है।

ऐसा करके हम यह जानने के लिए व्यवस्थापक को पूर्ण शक्ति दे सकते हैं कि किसने डेटा बदल दिया और यह कैसे बदला और रिकॉर्ड को अनावृत करने के लिए हमें केवल प्राथमिक डेटाबेस में हटाए गए ध्वज को बदलने की आवश्यकता है।

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

+0

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

2

मैंने पाया कि किसी ऑब्जेक्ट (सृजन, अद्यतन इत्यादि) के साथ किसी ऑब्जेक्ट का स्नैपशॉट लेना और उन स्नैपशॉट्स (तिथियों और उपयोगकर्ता जानकारी के साथ) को किसी अन्य तालिका में संग्रहीत करना आपको सभी प्रकार से मिल सकता है एक आवेदन के जीवनकाल में ऐतिहासिक ट्रैकिंग जरूरतों की जरूरत है। इसके बाद आप उपयोगकर्ता को स्नैपशॉट्स प्रस्तुत कर सकते हैं, उपयोगकर्ता को वर्तमान कालक्रम में परिवर्तन कर सकते हैं, किसी दिए गए दिनांक पर किसी ऑब्जेक्ट की स्थिति को घटा सकते हैं, आदि ..

मुझे यकीन है कि वहां आधिकारिक डिज़ाइन पैटर्न हैं - यह सिर्फ एक जिसे मैंने समय के साथ परिष्कृत किया है और यह अच्छी तरह से काम करता है। हालांकि डिस्क स्थान के साथ यह कुशल नहीं है।

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

+0

मैं इस विधि से पूरी तरह से सहमत हूं। – NotMe

+0

क्यों एक स्नैपशॉट, और लेनदेन नहीं? –

+0

@calico: मैं लेनदेन द्वारा मान रहा हूं कि आप क्या बदल रहे थे भंडारण का मतलब है और राज्य नहीं? मुझे यकीन है कि दोनों विधियां ऑडिटिंग के लिए काम करती हैं, लेकिन स्नैपशॉट विधि आपको किसी भी समय ऑब्जेक्ट की स्थिति को आसानी से निर्धारित करने की अनुमति देती है - हमें कई परियोजनाओं पर यह आवश्यकता है। – Mayo

0

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

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

वैसे, यह कॉलम से शुरू होने वाली इंडेक्स के साथ एक बूलियन (हाँ/नहीं) IsDeleted कॉलम होना बेहतर होगा। यह तेज़ होगा, हालांकि यह शायद मामले में काफी बड़ा अंतर नहीं करेगा।

+0

व्यापार तर्क का कौन सा हिस्सा "हटाया गया" नीचे आ जाएगा? उच्च प्रदर्शन डेटाबेस में कम मूल्य का डेटा क्यों रखा जाना चाहिए? –

+0

@Travis। दिलचस्प, एक डाउनवोट। क्या आप अपनी टिप्पणियों को स्पष्ट कर सकते हैं? पहला मैं कोई समझ नहीं सकता। दूसरे के लिए, आप मानते हैं कि ओपी का क्लाइंट यह जानना गलत है कि डेटा रखा गया है? इसलिए, उसकी मदद करने का मेरा प्रयास बुरा है, क्योंकि उसे ऐसा करने की कोशिश नहीं करनी चाहिए? मुझे उसे बताया जाना चाहिए था कि उसका ग्राहक उस डेटा को रखना गलत है? –

+0

आपको उसे बताया जाना चाहिए था कि उत्पादन डेटाबेस में बहिष्कृत डेटा रखना गलत था। –

0

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

3

स्थिति कॉलम का उपयोग न करें।

कम से कम आपके पास एक दिनांकित और हटाए गए कॉलम होना चाहिए। बस कुछ हटा दिया गया था, यह मददगार नहीं है, भले ही ग्राहक इसके लिए नहीं पूछ रहा है, भले ही वे हटाए गए कार्यक्रमों को देखने के लिए पहली बार जाएं, वे जानना चाहेंगे कि क्यों।

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

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

+0

मैं मानता हूं कि, किसी अन्य डेटाबेस का उपयोग करके कई स्पष्ट लाभ प्रदान किए जाते हैं जैसे प्रश्नों में क्लाउड तर्क नहीं करना या पुराने डेटा के साथ प्रदर्शन डीबी क्लाउड करना। –

0

इनमें से बहुत सारे टेबल के आकार पर निर्भर करता है और क्या आपको वास्तव में हटाने के बारे में additonal जानकारी की आवश्यकता है।

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

यदि आपके पास ऑडिटिंग है, तो आप पहले ही जानते हैं कि रिकॉर्ड को किसने हटा दिया और कब।

यदि नहीं, तो आपको उन फ़ील्ड को अपनी तालिका में जोड़ना चाहिए।

समय-समय पर, मैं मुख्य तालिका पर क्वेरी प्रदर्शन को लागू करने के लिए हटाए गए रिकॉर्ड्स को एक संग्रह तालिका में हटा सकता हूं। उन सभी हटाए गए रिकॉर्ड्स को स्थानांतरित करें जिन्हें 6 महीने से अधिक हटा दिया गया है। फिर एनोथ व्यू है जो व्यवस्थापक के लिए पूछताछ के लिए सामान्य तालिका और संग्रह तालिका दोनों को जोड़ती है।

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

0

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

तो यदि उपयोगकर्ता लॉग देख रहा है, तो आप इसके साथ जुड़े डेलेटी लेनदेन के बिना प्रत्येक लॉग पुनर्प्राप्त कर सकते हैं, हालांकि प्रशासक सबकुछ देख पाएंगे।

+0

बस स्पष्ट करने के लिए: मैं लेनदेन को लागू करने के लिए कमांड डिज़ाइन पैटर्न का उपयोग करूंगा। –

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