2011-03-26 22 views
10

मैं यह पता लगाने की कोशिश कर रहा हूं कि पूर्व-रेडो को अनुमति देने के लिए मेरी डीबी टेबल कैसे डिज़ाइन करें।पूर्ववत-रेडो के साथ एक एसक्यूएल डीबी कैसे डिजाइन करें?

मान लें कि आपने एक कार्य निम्नलिखित संरचना के साथ तालिका है:

id <int> 
title <varchar> 
memo <string> 
date_added <datetime> 
date_due <datetime> 

अब लगता है कि कुछ दिनों के और एकाधिक लॉग-इन है कि कई संपादन जगह ले लिया है से अधिक; लेकिन उपयोगकर्ता एक संस्करण में वापस जाना चाहता है।

  1. आप एक अलग तालिका में परिवर्तन पर नज़र रखने के लिए है चाहेंगे - या - आप (एक बेहतर शब्द की कमी के लिए "भूत" पंक्तियाँ,) कार्यों तालिका में परिवर्तन रखने के लिए कोशिश करेंगे?
  2. क्या आप सभी कॉलम ट्रैक करेंगे या केवल वे जो बदलते हैं?

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

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

आपकी मदद के लिए धन्यवाद।

+1

इसी तरह का प्रश्न यहां। [मेरा जवाब] पर एक नज़र डालें (http://stackoverflow.com/questions/5408828/are-there-problems-with-this-soft-delete-solution-using-eav-tables/5410359#5410359) – Ronnis

उत्तर

6

मैं आपकी कार्य तालिका के लिए एक इतिहास तालिका बनाउंगा। कार्यों के समान संरचना + पिछले आईडी नाम का एक नया फ़ील्ड। यह पिछली परिवर्तन आईडी रखेगा, ताकि आप विभिन्न परिवर्तनों (पूर्ववत/फिर से) के माध्यम से आगे जा सकें।

क्यों एक नई इतिहास तालिका? एक साधारण कारण के लिए: उन कार्यों के साथ कार्य तालिका को अधिभारित न करें जिन्हें इसे डिज़ाइन नहीं किया गया था।

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

अनुकूलन: और भी बेहतर, आप केवल तीन कॉलम इतिहास तालिका में रख सकते हैं: 1. taskId (कार्यों के लिए विदेशी कुंजी) 2 डेटा - एक बाइनरी क्षेत्र। इतिहास तालिका में सहेजने से पहले, केवल एक फ़ील्ड को बदलकर एक एक्सएमएल स्ट्रिंग बनाएं जो बदल गया है। 3. previousId (मदद मिलेगी परिवर्तन का एक कतार बनाए रखने और नेविगेशन आगे और पीछे की अनुमति देते हैं)

डेटा क्षेत्र का सवाल है, इस तरह एक XML स्ट्रिंग बनाने के लिए:

<task> 
    <title>Title was changed</title> 
    <date_added>2011-03-26 01:29:22<date_added> 
</task> 

यह मूलतः आपको बता देंगे कि इस बार आपने केवल शीर्षक और date_added फ़ील्ड बदल दिए हैं।

एक्सएमएल स्ट्रिंग के निर्माण के बाद, बस इसे ज़िप करें और इसे इतिहास तालिका के डेटा फ़ील्ड में संग्रहीत करें।

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

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

उम्मीद है कि इससे मदद मिलती है।

+0

द्वारा रास्ता, संपीड़न आपके टेक्स्ट आकार को मूल पाठ के 5% तक कम कर देगा। एक सामान्य मूल्य लगभग 10% है, लेकिन यदि आपके पास आम है, तो शब्दों को दोहराते हुए आपको बेहतर संपीड़न मिलता है। – Adi

+0

यह चालाक है, लेकिन मुझे यकीन नहीं है कि मैं "3 फ़ील्ड" विचार को समझता हूं। निश्चित रूप से इतिहास तालिका में प्रत्येक रिकॉर्ड का अपना आईडी फ़ील्ड (ऑटोइनक्रिकमेंट), कार्य रिकॉर्ड आईडी के लिए एक विदेशी लिंक होना चाहिए, और लागू होने पर पिछले इतिहास रिकॉर्ड आईडी का संदर्भ होना चाहिए (यानी एक ही कार्य रिकॉर्ड आईडी होना) ... या वहाँ sthg है मुझे समझ में नहीं आया है? –

+0

@ मिकरोडेंट मुझे लगता है कि आपको यह विचार मिला है, हमें 2 कुंजी की आवश्यकता है: एक कार्य तालिका (taskId) और एक इतिहास तालिका (पिछला आईडी) और साथ ही पेलोड (डेटा) जो बदल गया है ताकि आप इतिहास के आधार पर नेविगेट कर सकें taskId और पिछलेId फ़ील्ड पर और आवश्यक डेटा तक पहुंचने में भी सक्षम हो सकते हैं, यदि आवश्यक हो तो इसे बदल दें और पुनर्प्राप्त करें। – Adi

4

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

यदि आपके पास केवल एक एकल यूएनडीओ या इतिहास है, तो तालिका में ट्रैकिंग शायद ठीक है।

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

2

आप डेल्टा फॉर्म में संशोधन को संपीड़ित करना चाहते हैं लेकिन आपको अभी भी त्वरित पुनर्प्राप्ति के लिए पूर्ण संशोधन होना चाहिए।

हालांकि, पुराने डेल्टा के लिए पुरानी प्रसंस्करण की आवश्यकता होती है जब तक कि आपके पास कुछ गैर-डेल्टा आधार न हो। पुराने डेल्टा के लिए नए हर बार कुछ बदलावों को पुन: प्रसंस्करण की आवश्यकता होती है। तो डेल्टा आमतौर पर आपको कई लाभ नहीं मिलते हैं लेकिन अधिक जटिलता प्राप्त करते हैं।

अंतिम मैं जाँच की है, जो कुछ साल पहले, MediaWiki, विकिपीडिया के पीछे सॉफ्टवेयर, संग्रहीत पूरा पाठ और gzip से पुराने संशोधनों को संपीड़ित करने के लिए जगह है और नष्ट कर दिया संशोधन/पृष्ठों के लिए एक समर्पित तालिका archive को बचाने के लिए कुछ साधन उपलब्ध कराए।

उनकी वेबसाइट पर ER diagram of their database layout है जो आपको उपयोगी मिल सकता है।