डेटाबेस प्रविष्टियों के परिवर्तनों का इतिहास रखने के तरीके


21

डेटाबेस प्रविष्टियों (डेटा) के संस्करण की अनुमति देने के तरीके क्या हैं?

लेखों के वापस परिवर्तनों को वापस लाने के लिए सामग्री-प्रबंधन-प्रणाली क्षमताओं के बारे में सोचें।

उनके पेशेवरों / विपक्ष क्या हैं?


1
आप वास्तव में क्या संस्करण चाहते हैं? स्कीमा या डेटा?
tdammers

1
मैं डेटा को संस्करणित करना चाहता हूं। सेमी के उदाहरण पर बने रहने के लिए, लेखों के संस्करणों को कहने देता है ।
Matcauthon

आप डेटामिक में देखना चाह सकते हैं।
dan_waterworth

जवाबों:


19

मूल रूप से दो दृष्टिकोण हैं: एक ऑडिट टेबल, जिसमें पिछले सभी मान संग्रहीत हैं, या तालिका के भाग के रूप में एक शुरुआत / समाप्ति तिथि शामिल है, और सभी अपडेट पुराने को बंद करते हुए एक नया रिकॉर्ड बनाते हैं।

अपडेट: SQL SERVER 2016 इसे एक डिज़ाइन पैटर्न / टेबल प्रकार के रूप में समर्थन करता है - https://docs.microsoft.com/en-us/sql/relational-dat डेटाबेस/tables/temporal-tables?view=sql-server- 2017


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

1
यह आपके उपयोग पर निर्भर करेगा, यह टेबल / एस को आबाद करने के लिए ट्रिगर्स का उपयोग करने के लिए पर्याप्त हो सकता है और फिर रोलबैक करने के लिए क्या और कितनी दूर लेने का एक तरीका प्रदान करता है।
15 नवंबर को jororeno

आपके पास अपने उत्तर में एक टाइपो है (
पैटर को

7

एक विचार "इन्सर्ट-ओनली डेटाबेस" का उपयोग करना है। मूल विचार यह है कि आप कभी भी एक पंक्ति में डेटा को हटा या अपडेट नहीं करते हैं

ट्रैक करने के लिए आवश्यक प्रत्येक तालिका में दो datetimeकॉलम fromऔर होंगे to। वे NULLप्रत्येक में मूल्य के साथ शुरू करते हैं (समय से अंत तक की शुरुआत)। जब आपको उस पंक्ति को "बदलने" की आवश्यकता होती है जिसे आप एक नई पंक्ति जोड़ते हैं, और उसी समय आप toपिछली पंक्ति में Nowऔर उस पंक्ति में अपडेट करते हैं जिसे fromआप जोड़ रहे हैं Now

अधिक विस्तृत जानकारी के लिए देखें:

इस तकनीक को AuditTrailविरासत डेटा का प्रबंधन करने के लिए कहा जाता है, और इसके थोड़े स्टोर इतिहास को बदलते हैं।

ऐसा लगता है कि इस प्रकृति का प्रश्न पहले से ही पोस्ट किया गया है:


अफसोस की बात है कि यह सवाल हटा दिया गया है :(
डगलस गस्केल

कोई बात नहीं, यहाँ लिंक हैलिंक
Yusubov

2

मुझे लगता है कि आप प्रत्येक तालिका के लिए ट्रिगर का उपयोग कर सकते हैं और _history (या आप कोई भी नाम दे सकते हैं) में डेटा बनाए रख सकते हैं और अपडेट कर सकते हैं, मुख्य टेबल पर हटाएं आपके ट्रिगर को ट्रिगर करेंगे और आप इस तालिका में विवरण सहेज सकते हैं। यदि आप एक का उपयोग कर रहे हैं तो SQLite डेटाबेस के साथ भी उपलब्ध है।

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

प्रत्येक डेटाबेस को ट्रिगर लिखने और कोड करने का अपना तरीका है। यदि आप वाक्यविन्यास के लिए SQLite.org SQLite.org का उपयोग कर रहे हैं । अन्य डेटाबेस के लिए आप उनकी आधिकारिक साइटों पर जा सकते हैं।


1

आप शायद Sqlite DB इंजन के बारे में जानते हैं । पूरी db एक ही फाइल में सेव होती है। एपीआई वर्चुअल फाइल सिस्टम को भी सपोर्ट करता है इसलिए मूल रूप से आप स्टोरेज को कहीं भी और किसी भी फॉर्मेट में व्यवस्थित कर सकते हैं, बस विशेष फाइल ऑफसेट पर पढ़ने और लिखने के लिए प्रतिक्रिया दें। इसके लिए संभावित अनुप्रयोग एन्क्रिप्शन, संपीड़न और इतने पर हो सकते हैं। इसका सबसे अच्छा हिस्सा यह है कि कंटेनर परत को डेटाबेस, sql या sqlite फ़ाइल प्रारूप के बारे में कुछ भी नहीं पता होना चाहिए, बस xRead और xWrite कॉलबैक का पालन करना चाहिए।

विचारों में से एक टाइम-मशीन सुविधा को लागू करना था। तो कोई भी xWrite ऑपरेशन हर उस खंड को बचाता है जो इसे "पूर्ववत" इतिहास में अधिलेखित कर देगा और उपयोगकर्ता अतीत में एक तिथि चुन सकता है कि इसमें db सम्‍मिलित है (शायद केवल-पढ़ने के लिए मोड)। मेरे पास अभी तक काम करने का उदाहरण नहीं है ( साइक्लाइट मेल सूची में इसके बारे में चर्चा थी ), लेकिन शायद अन्य इंजन वीएफएस एपीआई की आपूर्ति करते हैं इसलिए ऐसा ही कुछ संभव है। और एक बार इसे लागू करने के बाद, यह किसी भी जटिलता के डेटाबेस संरचनाओं के साथ संगत होना चाहिए।


आपको क्या लगता है कि यह दृष्टिकोण बड़ी परियोजनाओं के लिए स्केलेबल है?
matcauthon

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

1

डेटाबेस प्रविष्टियों को संस्करणित करने के लिए हम जिस विधि का उपयोग करते हैं वह ऑडिटिंग टेबल का उपयोग करना है। तालिका की तर्ज पर एक स्कीमा है:

Seq      - Int      ' Unique identifier for this table
Event    - Char     ' Insert / Update / Delete
TblName  - Char     ' Table that had field value changed
FldName  - Char     ' Field that was changed
KeyValue - Char     ' delimited list of values for fields that make up the PK of table changed
UsrId    - Char     ' User who made the change
OldValue - Char     ' Old value (converted to character)
NewValue - Char     ' New value (converted to character)
AddTs    - DateTime ' When the change was made

फिर हमारे पास उन तालिकाओं को सम्मिलित / अद्यतन / हटाने पर ट्रिगर होता है जिन्हें हम ट्रैक करना चाहते हैं।

पेशेवरों:

  • सभी डेटा एक तालिका में है
  • किसी तालिका में सभी फ़ील्ड या विशिष्ट फ़ील्ड को ट्रैक करने के लिए सेटअप किया जा सकता है
  • तालिका के लिए प्रत्येक फ़ील्ड पर संस्करण दिखाना आसान है

विपक्ष:

  • एक तालिका में सभी ऑडिटिंग जानकारी होने के कारण रिकॉर्ड की एक बड़ी संख्या होती है
  • ट्रिगर्स की बहुत जरूरत है

0

मैं अब इसका एक संस्करण कर रहा हूं। हर रिकॉर्ड के लिए मेरे पास एक सम्मिलित तिथि, संशोधित तिथि और सक्रिय रिकॉर्ड बूलियन ध्वज है। प्रारंभिक सम्मिलित सम्मिलित और संशोधित तिथियों के लिए दोनों अभी () में है (यह उदाहरण एक्सेस में है) और सक्रिय रिकॉर्ड ध्वज के लिए सेट है true। फिर अगर मैं उस रिकॉर्ड को संशोधित करता हूं तो मैं पूरे मामले को एक नए रिकॉर्ड में कॉपी करता हूं, उपयोगकर्ता को बदल रहा है, उपयोगकर्ता बदल रहा है, मैं सम्मिलित दिनांक को मूल के बराबर छोड़ देता हूं और संशोधित तिथि को अब () में बदल देता हूं। मैं तो करने के लिए मूल रिकॉर्ड के सक्रिय रिकॉर्ड झंडा falseऔर करने के लिए नए रिकॉर्ड फ्लिप true। मेरे पास ModifiedRecordsParentID के लिए एक फ़ील्ड भी है जहां मैं मूल रिकॉर्ड की पहचान को सहेजता हूं।

तब अगर मुझे क्वेरी करने की आवश्यकता होती है तो मैं केवल रिकॉर्ड वापस कर सकता हूं जहां ActiveRecord = trueऔर मुझे केवल अधिकतम जानकारी प्राप्त होगी।


ActiveRecordझंडे की कोई जरूरत नहीं । MAX (*) पंक्ति हमेशा वर्तमान रिकॉर्ड होनी चाहिए। एक पिछले संस्करण के लिए बस आवेषण को बहाल करते हुए कहा कि तालिका में पंक्ति फिर से डालें।
invert

मुझे यकीन नहीं था कि कैसे काम का चयन करना है, लेकिन अब जब आप इसे बाहर बुला रहे हैं तो मैं इसके बारे में सोच रहा हूं और एक विचार है, हम्म
ब्रैड

आमतौर पर MAX (column_name) तालिका के कॉलम में सबसे बड़ा मान का चयन करता है। पूरी पंक्ति का चयन करने के लिए, एक सरल select top 1 order by id descendingकरना होगा।
उलट

हाँ, यह एक सरल एकल रिकॉर्ड के लिए काम करता है, लेकिन मेरी तालिका में बच्चे के रिकॉर्ड का एक संग्रह था, जिसे एक ही बार में चुनना होगा लेकिन व्यक्तिगत रूप से संशोधित किया जा सकता था। बस थोड़ा और जटिल है।
ब्रैड

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