इतिहास / लौकिक तालिकाओं के लिए सर्वोत्तम अभ्यास?


11

मान लीजिए कि मेरे पास एक वस्तु है, कुछ क्षेत्रों के साथ जो मैं इतिहास को ट्रैक करना चाहता हूं, और कुछ क्षेत्र जिन्हें मैं इतिहास को ट्रैक नहीं करना चाहता हूं। सामान्यीकरण के दृष्टिकोण से, निम्न स्कीमा ठीक है:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

जहां MyObjectHistory में नवीनतम संशोधन को छोड़कर सभी के लिए ट्रैक किए गए फ़ील्ड हैं। या, सभी ट्रैक किए गए फ़ील्ड एक तालिका में होने चाहिए, और नवीनतम सहित सभी संशोधन उस तालिका में होंगे:

CREATE TABLE MyObject AS (
    MyObjectId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectField1 VARCHAR(100) NOT NULL,
    MyObjectField2 VARCHAR(100) NOT NULL,
    MyObjectField3 VARCHAR(100) NOT NULL,
)
CREATE TABLE MyObjectHistory AS (
    MyObjectHistoryId INT IDENTITY NOT NULL PRIMARY KEY,
    MyObjectId INT NOT NULL FOREIGN KEY REFERENCES MyObject(MyObjectId),
    MyObjectTrackedField1 VARCHAR(100) NOT NULL,
    MyObjectTrackedField2 VARCHAR(100) NOT NULL,
    MyObjectTrackedField3 VARCHAR(100) NOT NULL,
)

मैं @ योएल
HaBo

जवाबों:


7

व्यावहारिक डेटा एक्सेस कारणों के लिए, आपको अपने पहले विकल्प से संरचना का उपयोग करना चाहिए, लेकिन इसके बजाय अपने इतिहास तालिका में वर्तमान संस्करण सहित अपने ट्रैक किए गए कॉलम मानों के सभी संस्करणों को रखें ।

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


2

मैं पहले संस्करण को पसंद करूंगा क्योंकि आपको शायद ही इतिहास को देखने की जरूरत है, लेकिन आपको वर्तमान मूल्य को देखने की आवश्यकता होगी। एक इतिहास तालिका को एक ट्रिगर से पॉप्युलेट किया जाना चाहिए, इसलिए आपको आमतौर पर सिंक्रोनाइज़ से निकलने वाले डेटा के बारे में चिंता करने की आवश्यकता नहीं है। तो मान लीजिए कि आपका MyObject में एक लाख रिकॉर्ड है और फिर MyObjectHistory में आपके पास 10,000,000 रिकॉर्ड हैं। क्या आप वास्तव में मौजूदा मूल्य प्राप्त करने के लिए कई रिकॉर्डों के साथ एक तालिका में शामिल होना चाहते हैं?

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

BTW मैं इतिहास तालिका में एक तारीख क्षेत्र जोड़कर बता पाऊंगा कि परिवर्तन किस क्रम में हुआ। आप अस्थायी आदेश के लिए पहचान पर भरोसा नहीं कर सकते। PLus यदि एक प्रीवियस मूल्य के बारे में कोई सवाल है और जब यह बदल गया है, तो आपको घुटने टेकने की आवश्यकता होगी। मैं उस अनुप्रयोग के लिए भी मान रख सकता हूँ जो परिवर्तन से आया है (यदि आपके पास कई अनुप्रयोग हैं) और / या वह व्यक्ति जिसने परिवर्तन किया है।


0

# 1 के लिए कुछ महत्वपूर्ण कारण हैं। पहले आकार का मुद्दा है HLGEM बताते हैं लेकिन अन्य महत्वपूर्ण भी हैं।

आमतौर पर आपके ऑडिट ट्रेल में समय के साथ आवश्यकताओं का विकास होता है। आप अंत में डेटाबेस उपयोगकर्ताओं, परिवर्तन के समय आदि को ट्रैक करना चाहते हैं। ऑडिट ट्रेल आवश्यकताओं और आपकी मुख्य तालिका समय के साथ कुछ हद तक स्वतंत्र रूप से बदलने की संभावना है। अंत में आप स्वतंत्र रूप से और पूरी तरह से अलग टेबल की अवधि के बाद ऑडिट ट्रेल डेटा को शुद्ध करना चाहते हैं।

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

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


2
"सामान्यीकृत भंडारण और अनुप्रयोग वस्तु मॉडल के बीच के अंतराल" से आपका क्या तात्पर्य है? क्या आप इस विचार को उजागर करेंगे या एक उदाहरण देंगे?
क्यूबेटोव 1729
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.