2012-06-11 15 views
5

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

उदाहरण: एक उपयोगकर्ता एक समय में एक चालान और सभी संदर्भों (ग्राहक का पता, पैसे की गणना की राशि, उत्पाद विवरण) जो इस चालान और गणना समय के साथ संग्रहित किया जाना चाहिए प्रतिबद्ध कर सकते हैं।

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

डेटाबेस डिज़ाइन के संबंध में यहां सबसे अच्छा अभ्यास क्या है? यहां तक ​​कि सबसे लचीला दृष्टिकोण क्या है उदा। जब उपयोगकर्ता बाद में अपना चालान संपादित करना चाहते हैं और इसे डीबी से बहाल करना चाहते हैं?

धन्यवाद!

उत्तर

9

यहाँ एक तरह से यह करने के लिए है। हम एक नया संस्करण बनाकर इसे "संशोधित" करते हैं। हम हटाए गए ध्वज को सेट करके इसे "हटाएं"।

उदाहरण के लिए:

  • उत्पाद की कीमत में परिवर्तन, तो हम PRODUCT_VERSION में एक नई पंक्ति सम्मिलित जबकि पुराने आदेश रखा जाता है पुराने PRODUCT_VERSION और पुराने मूल्य से जुड़ा है।
  • जब खरीदार पता बदलता है, तो हम बस पुराने संस्करण से जुड़े पुराने आदेशों को रखते हुए, CUSTOMER_VERSION में एक नई पंक्ति डालते हैं और उस पर नए ऑर्डर लिंक करते हैं।
  • यदि उत्पाद हटा दिया गया है, तो हम वास्तव में इसे हटा नहीं देते हैं - हमने बस PRODUCT.DELETED ध्वज सेट किया है, इसलिए उस उत्पाद के लिए ऐतिहासिक रूप से किए गए सभी ऑर्डर डेटाबेस में रहते हैं।
  • यदि ग्राहक हटा दिया गया है (उदा। क्योंकि वह अनियंत्रित होने का अनुरोध करता है), तो CUSTOMER.DELETED ध्वज सेट करें।

चेतावनियां:

  • उत्पाद का नाम अद्वितीय होने की जरूरत है, कि इसके बाद के संस्करण मॉडल में एलान के तौर पर लागू नहीं किया जा सकता है। आपको या तो PRODUCT_VERSION से PRODUCT तक NAME को "प्रचारित करने" की आवश्यकता होगी, इसे वहां एक कुंजी बनाएं और उत्पाद के नाम को "विकसित" करने की क्षमता दें, या केवल नवीनतम PRODUCT_VER (संभवतः ट्रिगर्स के माध्यम से) पर विशिष्टता लागू करें।
  • ग्राहक की गोपनीयता के साथ एक संभावित समस्या है। यदि किसी ग्राहक को सिस्टम से हटा दिया जाता है, तो यह डेटाबेस से अपने डेटा को भौतिक रूप से निकालने के लिए वांछनीय हो सकता है और केवल CUSTOMER.DELETED को सेट करने से ऐसा नहीं होगा। यदि यह कोई चिंता है, तो सभी ग्राहक के संस्करणों में गोपनीयता-संवेदनशील डेटा को खाली कर दें, या वैकल्पिक ग्राहक से मौजूदा ऑर्डर को वैकल्पिक रूप से डिस्कनेक्ट करें और उन्हें एक विशेष "अज्ञात" ग्राहक से दोबारा कनेक्ट करें, फिर भौतिक रूप से सभी ग्राहक संस्करणों को हटा दें।

यह मॉडल बहुत से पहचान संबंधों का उपयोग करता है। यह "वसा" विदेशी कुंजी की ओर जाता है और स्टोरेज समस्या का थोड़ा सा हो सकता है क्योंकि MySQL अग्रणी एज इंडेक्स संपीड़न (विपरीत, कहें, ओरेकल) का समर्थन नहीं करता है, लेकिन दूसरी तरफ पीके पर InnoDB always clusters the data और यह क्लस्टरिंग लाभकारी हो सकती है प्रदर्शन के लिए। इसके अलावा, जॉइन कम आवश्यक हैं।

पहचान रहित रिश्ते और किराए की कुंजी के साथ समतुल्य मॉडल इस प्रकार दिखाई देगा: दूसरी बात उसे मदद नहीं करेगा

enter image description here

+0

अद्वितीय उत्पाद नाम रखने के लिए, आप केवल उत्पाद नामों के साथ एक तालिका जोड़ सकते हैं, जहां नाम पीके है, और उस तालिका से PRODUCT_VERSION –

+0

@OweJessen से लिंक करें, निश्चित रूप से आपके पास अद्वितीय NAME के ​​साथ LATEST_PRODUCT_VERSION तालिका हो सकती है, लेकिन यह नहीं है "घोषणात्मक" समाधान के रूप में गिनें, क्योंकि आपको उस तालिका में पंक्तियों को मैन्युअल रूप से डालने और हटाने की आवश्यकता होगी क्योंकि नए उत्पाद संस्करण बनाए गए हैं। जब तक आप एक डीबीएमएस का उपयोग नहीं कर रहे हैं जो दोनों स्वचालित रूप से भौतिक दृश्यों को अपडेट कर सकते हैं और उन पर विशिष्टता लागू कर सकते हैं (जैसे एमएस एसक्यूएल सर्वर के अनुक्रमित विचार), इसलिए डीबीएमएस स्वयं आपके लिए LATEST_PRODUCT_VERSION बनाए रखता है। –

1

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

नाम परिवर्तनों से निपटने के लिए, आपको सीधे नाम का उपयोग करने के बजाय उत्पादों का संदर्भ देने के लिए आईडी का उपयोग करना चाहिए।

+0

कि अगर वह ऐतिहासिक उत्पाद का नाम शामिल करने के लिए के रूप में यह था, जब यह था चाहता है बेच दिया। वही आइटम आईडी 1 9 88 तक "कोक" पर लागू होता है और फिर बाद में "कोक क्लासिक" पर लागू होता है, और वह जानना चाहता है कि इसे पुराने आदेशों पर "कोक" कहा जाता था। आपका सुझाव वह है जो वह टालने का प्रयास कर रहा है - सामान्यीकृत डेटा का उपयोग करके उत्पन्न होने वाली कोई भी रिपोर्ट सभी आदेशों पर, "कोक क्लासिक" दिखाएगी, पूर्व-1988 या नहीं। – David

+0

सच .. इससे निपटने का एक तरीका नाम परिवर्तनों के लिए एक नया उत्पाद बनाना होगा, या उत्पाद नामों को ट्रैक करने के लिए एक और तालिका जोड़ें (जो @ ब्रैंको डिमिट्रीजेविक के समाधान तक पहुंचती है)। – whrrgarbl

1

जिस समस्या का आप सामना कर रहे हैं वह है, जैसा कि मुझे यकीन है कि आपको डेटाबेस सामान्यीकरण का नतीजा है। इसे हल करने के दृष्टिकोणों में से एक को बिजनेस इंटेलिजेंस तकनीक से लिया जा सकता है - Data Warehouse में डेटा इना डी-सामान्यीकृत डेटा संग्रहित करना।

सामान्यीकृत डेटा:

  • आदेश तालिका
    • OrderID
    • ग्राहक आईडी
  • ग्राहकों टेबल
    • ग्राहक आईडी
    • प्रथम
    • आदि
  • आइटम तालिका
    • Itemid
    • ITEMNAME
    • ItemPrice
  • ORDERDETAILS टेबल
    • ItemDetailId
    • OrderID
    • Itemid
    • ItemQty
    • आदि

जब पूछे और संग्रहीत de-सामान्यीकृत, डाटा वेयरहाउस तालिका लगता है कि

  • OrderID
  • ग्राहक आईडी
  • CUSTOMERNAME
  • CustomerAddress
  • (अन्य ग्राहक फील्ड्स)
  • ItemDetailId
  • Itemid
  • ITEMNAME
  • ItemPrice
  • (अन्य OrderDetail और आइटम फ़ील्ड)

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


ऊपर में शामिल भूमि के ऊपर का एक बहुत है, लेकिन अन्य आम तरीका है मैं के बारे में पता कर रहा हूँ और भी अधिक भूमि के ऊपर किया जाता है।

दूसरा दृष्टिकोण टेबल को केवल पढ़ने के लिए होगा।यदि कोई ग्राहक अपना पता बदलना चाहता है, तो आप अपना मौजूदा पता संपादित नहीं करते हैं, आप एक नया रिकॉर्ड डालते हैं।

तो अगर मेरा पता पता आईडी 12 है जब मैं पहली बार जामनी में अपनी साइट पर ऑर्डर करता हूं, तो मैं 4 जुलाई को चलता हूं, मुझे अपने खाते से जुड़ा एक नया पता मिलता है। (पता आईडी 123123 कहें क्योंकि आपकी साइट बहुत सफल है और ग्राहकों का एक टन आकर्षित किया है।)

आदेश 4 जुलाई से पहले मुझे पता चला कि उनके पास एड्रेसआईडी 12 होगा, और 4 जुलाई को या उसके बाद दिए गए आदेशों में पता आईडी 123123 है।

ऐतिहासिक डेटा को बनाए रखने के लिए आवश्यक प्रत्येक तालिका के साथ उस पैटर्न को दोहराएं।


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

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

+0

हां .... क्या @ डेविड स्ट्रैटन ने कहा ... एक ही विचार के मेरे अधिक बोलने वाले उत्तर को हटा रहा है। – GDP

+0

@ ग्रेग पी - मैं आपको वोट देने जा रहा था। आपका उत्तर अधिक संक्षेप में है, और अभी भी प्रासंगिक है। – David

+0

इसे पोस्टरिटी के लिए वापस जोड़ा गया ... हालांकि अधिक संक्षेप में जवाब देने पर दोहराया जाना पसंद नहीं है, धन्यवाद। – GDP

1

आपने शुद्ध और व्यावहारिक दृष्टिकोण के बीच एक शाश्वत बहस खोली है।

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

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

0

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

तो ऑर्डर तालिका में ग्राहक का नाम और पता हो सकता है, विवरण woudl में प्रोडक्ट के बारे में सभी प्रासंगिक जानकारी शामिल हैं, विशेष रूप से मूल्य (आप कभी भी समय की जानकारी के लिए उत्पाद तालिका पर भरोसा नहीं करना चाहते हैं आदेश)।

यह समय-समय पर डेटा बदलता नहीं है, लेकिन आपको ऐतिहासिक मूल्य की आवश्यकता है, इसलिए आपको इसे रिकॉर्ड करने के समय स्टोर करना होगा या आप डेटा अंतःक्रिया खो देंगे। आप नहीं चाहते हैं कि आपकी वित्तीय रिपोर्ट अचानक संकेत दे कि आपने पिछले साल 30% अधिक बेचा था क्योंकि आपके पास मूल्य अपडेट हैं। यही वह नहीं है जिसे आपने बेचा था।

enter image description here

अनिवार्य रूप से, हम को संशोधित करने या मौजूदा डेटा हटाने कभी नहीं:

+1

"यह denormalizing नहीं है ..." यह सही है। संबंधपरक प्रणालियों में, डुप्लिकेट डेटा का अर्थ है "समान अर्थ वाले समान मान"। यहां, मान समान हो सकते हैं, लेकिन अर्थ अलग है। (वर्तमान मूल्य, उदाहरण के लिए, आदेश के समय मूल्य बनाम।) –

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