एक चैंज / ऑडिटिंग डेटाबेस टेबल के लिए सर्वश्रेष्ठ डिज़ाइन? [बन्द है]


114

मुझे विभिन्न परिवर्तन लॉग / ऑडिटिंग (जब कुछ जोड़ा गया, हटाया, संशोधित किया गया, आदि) संग्रहीत करने के लिए एक डेटाबेस तालिका बनाने की आवश्यकता है। मुझे विशेष रूप से विस्तृत जानकारी संग्रहीत करने की आवश्यकता नहीं है, इसलिए मैं कुछ लाइनों के साथ सोच रहा था:

  • आईडी (घटना के लिए)
  • उपयोगकर्ता जो इसे ट्रिगर करता है
  • कार्यक्रम नाम
  • घटना विवरण
  • घटना का टाइमस्टैम्प

क्या मुझसे कोई चूक हो रही है? जाहिर है मैं डिजाइन में सुधार कर सकता हूं, हालांकि मैं इसे जटिल बनाने की योजना नहीं बनाता हूं (घटना प्रकार या सामान के लिए अन्य तालिकाओं को बनाना जैसे सवाल से बाहर है क्योंकि यह मेरी जरूरत के लिए एक जटिलता है)।


मैंने आपका उत्तर पढ़ा और मुझे आश्चर्य हुआ कि कोई भी कानून के बारे में बात नहीं करता है। मुझे पता है कि कुछ कानून या अच्छे pratice दस्तावेज़ बताते हैं कि हम कैसे (केवल पढ़ें) ऑडिट टेबल को लागू करते हैं। लेकिन मुझे इससे ज्यादा जानकारी नहीं है। मुझे सिर्फ इतना पता है कि यह मौजूद है। मैं CFR 21 भाग 11 में ऑडिट ट्रेल के बारे में सोच रहा हूँ
बस्तियन वंदामे

जवाबों:


69

मैं जिस प्रोजेक्ट पर काम कर रहा हूं, उसमें ऑडिट लॉग भी बहुत कम से कम डिजाइन से शुरू हुआ था, जैसे आपने बताया था:

event ID
event date/time
event type
user ID
description

विचार समान था: चीजों को सरल रखना।

हालांकि, यह जल्दी से स्पष्ट हो गया कि यह न्यूनतर डिजाइन पर्याप्त नहीं था। इस तरह के सवालों के लिए विशिष्ट ऑडिट उबल रहा था:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

इसलिए, ऐसे प्रश्नों का शीघ्रता से (एसक्यूएल का उपयोग करके) उत्तर देने में सक्षम होने के लिए, हमने ऑडिट टेबल में दो अतिरिक्त कॉलम समाप्त किए

object type (or table name)
object ID

जब हमारे ऑडिट लॉग का डिज़ाइन वास्तव में स्थिर हो जाता है (अब कुछ वर्षों के लिए)।

बेशक, अंतिम "सुधार" केवल उन तालिकाओं के लिए काम करेगा जिनके पास सरोगेट कुंजी थी। लेकिन अंदाज़ा लगाओ कि क्या है? हमारे सभी तालिकाओं कि लेखा परीक्षा के लायक ऐसी एक कुंजी है!


एकमात्र समस्या जो मुझे इस डिज़ाइन ('विवरण-आधारित ऑडिट ट्रेल) के साथ है, उस क्षेत्र में प्रयुक्त भाषा को स्थानीय बनाने के साथ है।
सैम विल्सन

@ मैं इस तरह की समस्या नहीं देखता, यदि संदेश सिस्टम उत्पन्न होता है, तो अनुवाद स्ट्रिंग के लिए यहां एक कुंजी का उपयोग करें;
JCM

4
@ हीरू: जब आप एक कॉलम में दो या दो से अधिक विशिष्ट अवधारणाओं को "मिंगल" करते हैं, तो अधिक से अधिक यह बैकफ़ायर, जितनी जल्दी या बाद में नहीं होता है। उदाहरण के लिए, यदि आप ईवेंट प्रकार और ऑब्जेक्ट प्रकार "मेलिंग" करते हैं, तो यह प्रश्नों को प्रभावित करेगा जैसे "मुझे दिए गए प्रकार के सभी ऑब्जेक्ट के लिए रिकॉर्ड दिखाएं" और "मुझे दिए गए प्रकार के सभी ईवेंट के लिए रिकॉर्ड दिखाएं" (प्रश्न अधिक होंगे जटिल और सबसे अधिक संभावना बहुत धीमी गति से काम करेगा)।
यारिक

3
इन स्तंभों के अलावा, किसी के पास संरचित विवरण / संरचित घटना पेलोड के लिए एक अतिरिक्त स्तंभ हो सकता है । यह कॉलम कंप्यूटर-पठनीय प्रारूप, XML / JSON में ईवेंट विवरण (जो भी जटिलता का) धारण करेगा। के बारे में तर्क करने के लिए, कम से कम (Postgres / MSSQL में) के खिलाफ क्वेरी करने के लिए आसान है।
turdus-merula

1
@ बैंजामिन: इसका जवाब डोमेन मॉडल (उर्फ बिजनेस मॉडल) में है। यदि मॉडल एक साथ संस्थाओं के निर्माण की अनुमति देता है (जैसे कि तार्किक लेनदेन के एक भाग के रूप में) तो मुझे एक ही टाइमस्टैम्प के साथ कई लॉग रिकॉर्ड होने में कोई समस्या नहीं दिखाई देती है। उदाहरण के लिए, यदि खरीद ऑर्डर का निर्माण (लेनदेन के रूप में) में एन ऑर्डर आइटम का निर्माण शामिल हो सकता है, तो सभी संबंधित 1 + एन लॉग रिकॉर्ड्स में समान टाइमस्टैम्प होगा। इस तरह के लॉग के बाद के विश्लेषण ने इसका लाभ उठाया, इन 1 + एन रिकॉर्डों को स्वतंत्र नहीं, बल्कि एक तार्किक लेनदेन के तत्वों के रूप में माना गया। आशा है कि यह समझ में आता है।
यारिक

24

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

जब आप डिज़ाइन कर रहे हों, तो आपको डेटा पुनर्प्राप्त करने के लिए कोड लिखना चाहिए। जब आपको ठीक होने की आवश्यकता होती है, तो यह आमतौर पर जल्दी में होता है, पहले से ही तैयार होने के लिए सबसे अच्छा।


1
यह वास्तव में अच्छा है। मुझे समझ में नहीं आता कि लोग अंतिम पोस्ट को क्यों अनदेखा करते हैं।
मैडी.शिक

3
इवेंट सोर्सिंग इतिहास को बनाए रखते हुए रोल-बैक कार्यक्षमता प्रदान करने का एक वैकल्पिक तरीका है।
सैम

23

ऐसी कई और चीज़ें हैं जिन्हें आप ऑडिट करना चाहते हैं, जैसे टेबल / कॉलम नाम, कंप्यूटर / एप्लिकेशन जिसमें से एक अपडेट किया गया था, और बहुत कुछ।

अब, यह इस बात पर निर्भर करता है कि आपको वास्तव में किस स्तर पर और किस स्तर की आवश्यकता है।

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

सुझाव:

  • मूल्यों से पहले / बाद में शामिल करें

  • प्राथमिक कुंजी संग्रहीत करने के लिए 3-4 कॉलम शामिल करें (यदि यह एक समग्र कुंजी है)

  • रॉबर्ट द्वारा सुझाए गए अनुसार मुख्य डेटाबेस के बाहर डेटा स्टोर करें

  • रिपोर्ट तैयार करने में समय की एक अच्छी राशि खर्च करें - विशेष रूप से उन लोगों के लिए जिन्हें आपको वसूली की आवश्यकता हो सकती है

  • होस्ट / एप्लिकेशन नाम के भंडारण की योजना - यह संदिग्ध गतिविधियों पर नज़र रखने के लिए बहुत उपयोगी हो सकती है


2
आप इसे खरीदने के बजाय इंजीनियर को क्यों उलट देंगे?
जौन

1
उत्पाद पर अधिक नियंत्रण
Tebe

1
आशा है कि उन्होंने आप पर मुकदमा नहीं किया।
सॉर्टर

9

यहां और इसी तरह के सवालों में बहुत सारे दिलचस्प जवाब हैं। केवल वही चीजें जो मैं व्यक्तिगत अनुभव से जोड़ सकता हूं:

  1. अपनी ऑडिट टेबल को दूसरे डेटाबेस में रखें। आदर्श रूप से, आप मूल डेटा से अलगाव चाहते हैं। यदि आपको अपने डेटाबेस को पुनर्स्थापित करने की आवश्यकता है, तो आप वास्तव में ऑडिट ट्रेल को पुनर्स्थापित नहीं करना चाहते हैं।

  2. यथोचित रूप से जितना संभव हो उतना कम करें। आप चाहते हैं कि तालिका में मूल डेटा के लिए कुछ निर्भरताएँ हों। डेटा प्राप्त करने के लिए ऑडिट टेबल को सरल और तेज़ होना चाहिए। डेटा पाने के लिए कोई भी कल्पना अन्य तालिकाओं में शामिल नहीं होती है।


8
क्या उचित अनुक्रमित वाले सामान्यीकृत डेटा की तुलना में अप्राकृतिक डेटा वास्तव में पढ़ने में तेज़ होगा? (HDD से अधिक डेटा पढ़ने में सभी दोहराव परिणाम नहीं होंगे?)
सैम

4

हमारी तालिका में हमारे पास क्या है: -

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

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


2
"राशि" क्या दर्शाता है?
turdus-merula

यह एक वित्तीय अनुप्रयोग है, इसलिए यह अधिकृत होने वाली चीज़ का डॉलर मूल्य है, आदि
WW।

4

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


3

इसे करने के कई तरीके हैं। मेरा पसंदीदा तरीका है:

  1. mod_userअपनी स्रोत तालिका में एक फ़ील्ड जोड़ें (जिसे आप लॉग इन करना चाहते हैं)।

  2. एक लॉग टेबल बनाएं, जिसमें वे फ़ील्ड हैं जिन्हें आप लॉग इन करना चाहते हैं, साथ ही ए log_datetimeऔर seq_numफ़ील्ड। seq_numप्राथमिक कुंजी है।

  3. स्रोत तालिका पर एक ट्रिगर बनाएँ जो किसी भी मॉनिटर किए गए फ़ील्ड को बदलने पर वर्तमान रिकॉर्ड को लॉग टेबल में सम्मिलित करता है।

अब आपको हर परिवर्तन का रिकॉर्ड मिल गया है और जिसने इसे बनाया है।


तो ... mod_user फ़ील्ड को क्या करना चाहिए?
शंकु

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

हटाने के बारे में क्या, फिर? यदि आप एक पंक्ति हटाते हैं, तो आप mod_user कॉलम के लिए मान कैसे संभालते हैं?
केएन कैल

@KennCal ट्रिगर वर्चुअल टेबल का उपयोग कर सकते हैं, आप एक ही ट्रिगर के अंदर और बाद में डेटा देख सकते हैं। ऑपरेशन से कोई फर्क नहीं पड़ता। stackoverflow.com/questions/6282618/…
रेनन कैवेलियरी

2
@KennCal आप सही हैं, डिलीट ट्रिगर को आपके लिए उस जानकारी को स्टोर करना होगा। शैतान विवरण में है - यदि आप SQL प्रमाणीकरण का उपयोग कर रहे हैं, तो ट्रिगर बस [CURRENT_USER] का चयन कर सकता है। यदि यह एक क्लाइंट एप्लिकेशन है, तो क्लाइंट कोड को यह घोषणा करने की आवश्यकता है कि यह कौन है। यदि यह एक एपीआई कॉल है, तो उपयोगकर्ता को हटाने के लिए कॉल के लिए एक आवश्यक पैरामीटर होना चाहिए।
जोसेफटन्स

1

पृथक्करण के सिद्धांत के अनुसार:

  1. ऑडिटिंग डेटा टेबल को मुख्य डेटाबेस से अलग करने की आवश्यकता है। क्योंकि ऑडिट डेटाबेस में बहुत सारे ऐतिहासिक डेटा हो सकते हैं, यह उन्हें अलग रखने के लिए मेमोरी उपयोग के दृष्टिकोण से समझ में आता है।

  2. पूरे डेटाबेस को ऑडिट करने के लिए ट्रिगर्स का उपयोग न करें, क्योंकि आप समर्थन करने के लिए विभिन्न डेटाबेस की गड़बड़ी को समाप्त करेंगे। आपको DB2, SQLServer, Mysql, आदि के लिए एक लिखना होगा।

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