2010-09-20 12 views
12

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

क्या हर बदलाव के इतिहास को मालिक और मूल्य में रखने के लिए एक अच्छा डिज़ाइन है। मैं इसे कई तालिकाओं के लिए करना चाहता हूं। तालिका के एक लेखापरीक्षा की तरह।

क्या मैं क्षेत्रों

table_name, field_name, prev_value, current_val, time, user के साथ एक एकल मेज रखने गया था सोचा।

लेकिन यह हैकी और बदसूरत दिखता है। क्या कोई बेहतर डिजाइन है?

धन्यवाद।

उत्तर

21

कुछ दृष्टिकोण

फील्ड आधारित

audit_field (table_name, id, field_name, field_value, datetime) 

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

फील्ड_वल्यू को कभी-कभी मूल फ़ील्ड से वास्तविक फ़ील्ड प्रकार का समर्थन करने के लिए कई फ़ील्ड में विभाजित किया जाता है (लेकिन केवल उन फ़ील्ड में से एक भर जाएगा, इसलिए डेटा denormalized है; एक संस्करण ऊपर तालिका को एक टेबल में विभाजित करना है प्रत्येक प्रकार के लिए)।

फ़ील्ड_टाइप, user_id, user_ip, क्रिया (अद्यतन, हटाएं, डालने) आदि जैसे अन्य मेटा डेटा उपयोगी हो सकते हैं।

ऐसे रिकॉर्डों की संरचना का उपयोग करने के लिए सबसे अधिक परिवर्तन करने की आवश्यकता होगी।

आधारित

audit_table_name (timestamp, id, field_1, field_2, ..., field_n) 

रिकार्ड डेटाबेस में प्रत्येक रिकॉर्ड प्रकार एक सामान्यीकृत तालिका मूल रिकॉर्ड के रूप में सभी क्षेत्रों के अलावा एक संस्करण क्षेत्र (अतिरिक्त मेटा डेटा फिर संभव हो तो) है कि बनाने के लिए। प्रत्येक कार्य तालिका के लिए एक टेबल आवश्यक है। ऐसी तालिकाओं को बनाने की प्रक्रिया स्वचालित हो सकती है।

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

लॉग फ़ाइल

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

+0

यह पूर्ण लगता है। मुझे आश्चर्य है कि प्रत्येक दृष्टिकोण के लिए प्रदर्शन कैसा होगा। तो रिकॉर्ड आधारित में, संस्करण फ़ील्ड के साथ दर्पण तालिका (फ़ील्ड के संदर्भ में) होगी? – saint

+1

@ संत, प्रदर्शन एक समग्र है, यह उपयोग पैटर्न पर निर्भर करता है। लॉग फ़ाइल लिखने के लिए सबसे तेज़ होगा (esp। अगर अलग विभाजन या अलग नोड)। और निश्चित रूप से आप बहुत कुछ लिखेंगे। अब, पढ़ना कितना महत्वपूर्ण है? यदि आप एक सप्ताह में एक बार पढ़ना चाहते हैं तो यह विभिन्न क्षेत्रों के बीच समयरेखा सहसंबंध की जांच करने या कुछ अन्य डेटा खनन (चरम उदाहरण के रूप में) की तुलना में एक अलग बात है। – Unreason

+0

@ संत, हां, रिकॉर्ड आधारित में आप वर्जनिंग फ़ील्ड (और संभवतः उपयोगकर्ता के रूप में अन्य रोचक मेटाडेटा) के साथ तालिकाओं का विस्तार करते हैं। – Unreason

4

हमारी परियोजनाओं में हम आम तौर पर यह इस तरह से कार्य करें: आप एक मेज

properties(ID, value1, value2) 

तो आप तालिका जोड़ने

properties_audit(ID, RecordID, timestamp or datetime, value1, value2) 

ID इतिहास रिकॉर्ड की एक आईडी -is है (वास्तव में आवश्यक नहीं)

RecordID-मूल गुण तालिका में रिकॉर्ड के लिए अंक।

जब आप properties तालिका अपडेट करते हैं तो आप properties में अपडेट किए गए रिकॉर्ड के पिछले मानों के साथ properties_audit पर नया रिकॉर्ड जोड़ते हैं। यह ट्रिगर्स या आपके डीएएल में इस्तेमाल किया जा सकता है।

इसके बाद आपके पास properties और properties_audit में सभी इतिहास (पिछले मान) में नवीनतम मूल्य है।

2

मुझे लगता है कि एक सरल स्कीमा

table_name, field_name, value, time, userId 

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

+0

आप सही हैं, अनावश्यक लगता है। बस बिना सोच के टाइप किया। – saint

+1

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

6

इस पर देखने के लिए एक अलग तरीका डेटा को समय-आयाम करना है।

अपनी मेज मान लिया जाये कि इस तरह दिखता है:

create table my_table (
my_table_id  number  not null primary key, 
attr1   varchar2(10) not null, 
attr2   number   null, 
constraint my_table_ak unique (attr1, att2)); 

तो अगर आप इसे इतना तरह बदल दिया है:

create table my_table (
my_table_id  number  not null, 
attr1   varchar2(10) not null, 
attr2   number   null, 
effective_date date   not null, 
is_deleted  number(1,0) not null default 0, 
constraint my_table_ak unique (attr1, att2, effective_date) 
constraint my_table_pk primary key (my_table_id, effective_date)); 

आप ऑनलाइन हैं और उपलब्ध, My_table की एक पूरी चल इतिहास है करने में सक्षम हो जाएगा । आपको INSERT गतिविधि में अद्यतन गतिविधि को अवरुद्ध करने के लिए प्रोग्रामों के प्रतिमान (या डेटाबेस ट्रिगर्स का उपयोग) को बदलना होगा, और DELETE गतिविधि को IS_DELETED बूलियन को UPDATING में बदलने के लिए बदलना होगा।


कारण:

आप सही है कि इसी तरह इस समाधान रिकॉर्ड के आधार पर करने के लिए लेखा परीक्षा कर रहे हैं; मैंने इसे शुरुआत में एक स्ट्रिंग में खेतों के एक संयोजन के रूप में पढ़ा, जिसे मैंने देखा है। मैं क्षमाप्रार्थी हूं।

तालिका में समय-आयाम के बीच प्राथमिक अंतर और प्रदर्शन या स्केलेबिलिटी बलिदान के बिना रखरखाव के आसपास रिकॉर्ड आधारित ऑडिटिंग सेंटर का उपयोग करना।

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

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

प्रदर्शन और मापनीयता: यदि कोई प्रभावी/समाप्ति दिनांक कॉलम पर समय-आयामी तालिका को विभाजित करता है, तो सक्रिय रिकॉर्ड एक "तालिका" में होते हैं, और निष्क्रिय रिकॉर्ड दूसरे में होते हैं। वास्तव में आपके समाधान से कम स्केलेबल कैसा है? "हटाना" और सक्रिय रिकॉर्ड में ओरेकल में पंक्ति आंदोलन शामिल है, जो कवर के तहत एक डिलीट-एंड-डार्ट है - वास्तव में रिकॉर्ड-आधारित समाधान की आवश्यकता होगी।

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

संक्षेप में, यह एक डिज़ाइन विकल्प है; मुझे यकीन नहीं है कि या तो सही है या गलत है।

+0

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

+0

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

+0

यह साफ दिखता है, मुझे यकीन नहीं है कि मैं अद्वितीय प्रभावी तिथि के उपयोग को समझता हूं? – saint

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