क्या रिकॉर्ड में परिवर्तनों के इतिहास को ट्रैक करने के लिए एक MySQL विकल्प / सुविधा है?


122

मुझसे पूछा गया है कि क्या मैं MySQL डेटाबेस में रिकॉर्ड्स में बदलाव का ट्रैक रख सकता हूं। इसलिए जब एक फ़ील्ड को बदला गया है, तो पुराना बनाम नया उपलब्ध है और यह जिस तारीख को हुआ है। क्या ऐसा करने के लिए कोई विशेषता या सामान्य तकनीक है?

यदि हां, तो मैं ऐसा कुछ करने की सोच रहा था। नामक एक तालिका बनाएँ changes। इसमें मास्टर टेबल के समान फ़ील्ड शामिल होंगे लेकिन पुराने और नए के साथ उपसर्ग किया जाएगा, लेकिन केवल उन फ़ील्ड्स के लिए जिन्हें वास्तव में बदल दिया गया था और TIMESTAMPइसके लिए। यह एक के साथ अनुक्रमित किया जाएगा ID। इस तरह, SELECTप्रत्येक रिकॉर्ड के इतिहास को दिखाने के लिए एक रिपोर्ट चलाई जा सकती है। क्या यह एक अच्छी विधि है? धन्यवाद!

जवाबों:


83

यह सूक्ष्म है।

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

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

इसके बजाय, आप समय के साथ बदलाव की अवधारणा को अपने स्कीमा डिज़ाइन में बदल सकते हैं (यह दूसरा विकल्प केथानजन सुझाव देते हैं)। यह आपके आवेदन में परिवर्तन है, निश्चित रूप से व्यावसायिक तर्क और दृढ़ता के स्तर पर, इसलिए यह तुच्छ नहीं है।

उदाहरण के लिए, यदि आपके पास एक तालिका है:

CUSTOMER
---------
CUSTOMER_ID PK
CUSTOMER_NAME
CUSTOMER_ADDRESS

और आप समय के साथ नज़र रखना चाहते थे, आप इसे इस प्रकार संशोधित करेंगे:

CUSTOMER
------------
CUSTOMER_ID            PK
CUSTOMER_VALID_FROM    PK
CUSTOMER_VALID_UNTIL   PK
CUSTOMER_STATUS
CUSTOMER_USER
CUSTOMER_NAME
CUSTOMER_ADDRESS

हर बार जब आप ग्राहक रिकॉर्ड बदलना चाहते हैं, तो रिकॉर्ड को अपडेट करने के बजाय, आपने वर्तमान रिकॉर्ड पर अब () को VALID_UNTIL सेट किया है, और VALID_FROM (अब) और एक शून्य VALID_UNTIL के साथ एक नया रिकॉर्ड डालें। आप "CUSTOMER_USER" स्थिति को वर्तमान उपयोगकर्ता की लॉगिन आईडी पर सेट करें (यदि आपको इसे रखने की आवश्यकता है)। यदि ग्राहक को हटाने की आवश्यकता है, तो आप इसे इंगित करने के लिए CUSTOMER_STATUS ध्वज का उपयोग करते हैं - आप इस तालिका से रिकॉर्ड कभी नहीं हटा सकते।

इस तरह, आप हमेशा पा सकते हैं कि दी गई तारीख के लिए ग्राहक तालिका की स्थिति क्या थी - पता क्या था? क्या उन्होंने नाम बदल दिया है? इसी तरह के मान्य_फ्रेम और मान्य_ऑनटाइल तारीखों के साथ अन्य तालिकाओं में शामिल होकर, आप पूरी तस्वीर को ऐतिहासिक रूप से फिर से बना सकते हैं। वर्तमान स्थिति जानने के लिए, आप एक शून्य VALID_UNTIL दिनांक के साथ रिकॉर्ड खोजते हैं।

यह स्पष्ट नहीं है (कड़ाई से बोलते हुए, आपको valid_from की आवश्यकता नहीं है, लेकिन यह प्रश्नों को थोड़ा आसान बनाता है)। यह आपके डिज़ाइन और आपके डेटाबेस की पहुँच को जटिल करता है। लेकिन यह दुनिया को बहुत आसान बनाने का पुनर्निर्माण करता है।


लेकिन यह उन क्षेत्रों के लिए डुप्लिकेट डेटा जोड़ देगा जिन्हें अपडेट नहीं किया गया है? इसे कैसे प्रबंधित करें?
itzmukeshy7

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

सबसे अच्छा सुझाव मैंने अभी तक इस समस्या को देखा है
वॉर्थी 7

ओह, और टिप्पणियों के जवाब में, कैसे बस के बारे में सब कुछ है कि नहीं बदला के लिए अशक्त भंडारण? तो नवीनतम संस्करण सभी नवीनतम डेटा का होगा, लेकिन यदि नाम 5 दिन पहले "बॉब" हुआ करता था, तो बस एक पंक्ति, नाम = बॉब और 5 दिन पहले तक मान्य होगा।
वर्थ 7

2
Customer_id और तिथियों का संयोजन प्राथमिक कुंजी है, इसलिए उन्हें अद्वितीय गारंटी दी जाएगी।
नेविल कुइट

186

यहाँ यह करने का एक सीधा तरीका है:

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

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

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

इतिहास तालिका बनाने में काफी आसान है। नीचे तालिका में क्वेरी (और उसके नीचे ट्रिगर प्रश्नों में), अपने डेटा तालिका में उस कॉलम के वास्तविक नाम के साथ 'प्राथमिक_की_ कॉलम' को बदलें।

CREATE TABLE MyDB.data_history LIKE MyDB.data;

ALTER TABLE MyDB.data_history MODIFY COLUMN primary_key_column int(11) NOT NULL, 
   DROP PRIMARY KEY, ENGINE = MyISAM, ADD action VARCHAR(8) DEFAULT 'insert' FIRST, 
   ADD revision INT(6) NOT NULL AUTO_INCREMENT AFTER action,
   ADD dt_datetime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER revision,
   ADD PRIMARY KEY (primary_key_column, revision);

और फिर आप ट्रिगर बनाते हैं:

DROP TRIGGER IF EXISTS MyDB.data__ai;
DROP TRIGGER IF EXISTS MyDB.data__au;
DROP TRIGGER IF EXISTS MyDB.data__bd;

CREATE TRIGGER MyDB.data__ai AFTER INSERT ON MyDB.data FOR EACH ROW
    INSERT INTO MyDB.data_history SELECT 'insert', NULL, NOW(), d.* 
    FROM MyDB.data AS d WHERE d.primary_key_column = NEW.primary_key_column;

CREATE TRIGGER MyDB.data__au AFTER UPDATE ON MyDB.data FOR EACH ROW
    INSERT INTO MyDB.data_history SELECT 'update', NULL, NOW(), d.*
    FROM MyDB.data AS d WHERE d.primary_key_column = NEW.primary_key_column;

CREATE TRIGGER MyDB.data__bd BEFORE DELETE ON MyDB.data FOR EACH ROW
    INSERT INTO MyDB.data_history SELECT 'delete', NULL, NOW(), d.* 
    FROM MyDB.data AS d WHERE d.primary_key_column = OLD.primary_key_column;

और आपने कल लिया। अब, 'MyDb.data' में सभी आवेषण, अपडेट और डिलीट 'MyDb.data_history' में दर्ज किए जाएंगे, जो आपको इस तरह से एक इतिहास तालिका प्रदान करते हैं (शून्य से 'data_columns' कॉलम को घटाते हुए)

ID    revision   action    data columns..
1     1         'insert'   ....          initial entry for row where ID = 1
1     2         'update'   ....          changes made to row where ID = 1
2     1         'insert'   ....          initial entry, ID = 2
3     1         'insert'   ....          initial entry, ID = 3 
1     3         'update'   ....          more changes made to row where ID = 1
3     2         'update'   ....          changes made to row where ID = 3
2     2         'delete'   ....          deletion of row where ID = 2 

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

CREATE VIEW data_history_changes AS 
   SELECT t2.dt_datetime, t2.action, t1.primary_key_column as 'row id', 
   IF(t1.a_column = t2.a_column, t1.a_column, CONCAT(t1.a_column, " to ", t2.a_column)) as a_column
   FROM MyDB.data_history as t1 INNER join MyDB.data_history as t2 on t1.primary_key_column = t2.primary_key_column 
   WHERE (t1.revision = 1 AND t2.revision = 1) OR t2.revision = t1.revision+1
   ORDER BY t1.primary_key_column ASC, t2.revision ASC

संपादित करें: अरे वाह, 6 साल पहले से मेरे इतिहास की मेज की तरह लोग: पी

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

किसी विशेष क्रम में कुछ टिप्पणियों को संबोधित करने के लिए:

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

  • यदि प्राथमिक कुंजी और संशोधन कॉलम के बीच संबंध बंद हो जाता है, तो इसका मतलब आमतौर पर समग्र कुंजी किसी न किसी तरह से बोर हो जाती है। कुछ दुर्लभ अवसरों पर मैंने ऐसा किया था और इस कारण से नुकसान हुआ था।

  • मैंने इस समाधान को बहुत अच्छा प्रदर्शन करने वाला पाया, जैसे कि यह ट्रिगर करता है। इसके अलावा, MyISAM आवेषण में तेज है, जो सभी ट्रिगर्स करते हैं। आप इसे स्मार्ट इंडेक्सिंग (या कमी ...) के साथ आगे सुधार सकते हैं। एक प्राथमिक कुंजी के साथ एक MyISAM तालिका में एक पंक्ति को सम्मिलित करना एक ऐसा ऑपरेशन नहीं होना चाहिए, जिसे आपको वास्तव में अनुकूलित करने की आवश्यकता हो, जब तक कि आपके पास महत्वपूर्ण मुद्दे कहीं और न हों। पूरे समय में मैं MySQL डेटाबेस चला रहा था यह इतिहास तालिका कार्यान्वयन चालू था, यह कभी भी (कई) प्रदर्शन समस्याओं में से किसी का कारण नहीं था।

  • यदि आपको बार-बार आवेषण मिल रहे हैं, तो INSERT IGNORE प्रकार के प्रश्नों के लिए अपनी सॉफ़्टवेयर परत की जाँच करें। हम्म, अब याद नहीं कर सकते हैं, लेकिन मुझे लगता है कि इस योजना और लेनदेन के साथ मुद्दे हैं जो अंततः कई डीएमएल क्रियाओं को चलाने के बाद विफल हो जाते हैं। कुछ के बारे में पता होना चाहिए, कम से कम।

  • यह महत्वपूर्ण है कि इतिहास तालिका और डेटा तालिका के क्षेत्र मेल खाते हैं। या, बल्कि, कि आपकी डेटा तालिका में इतिहास तालिका की तुलना में अधिक स्तंभ नहीं हैं। अन्यथा, डेटा टेबल पर इंसर्ट / अपडेट / डेल क्वैश्चंस फेल हो जाएंगे, जब हिस्ट्री टेबल पर इंसर्ट्स क्वेरी में कॉलम डालते हैं जो मौजूद नहीं हैं (ट्रिगर क्वेरी में d। * के कारण), और ट्रिगर विफल हो जाता है। t भयानक होगा यदि MySQL में स्कीमा-ट्रिगर जैसा कुछ होता है, जहां आप इतिहास तालिका को बदल सकते हैं यदि स्तंभों को डेटा तालिका में जोड़ा गया था। क्या MySQL अब है? मैं इन दिनों रिएक्ट करता हूं: पी


3
मैं वास्तव में इस समाधान की तरह। हालांकि अगर आपकी मुख्य तालिका में कोई प्राथमिक कुंजी नहीं है या आप नहीं जानते कि प्राथमिक क्या है, तो यह थोड़ा मुश्किल है।
बेंजामिन एकस्टीन

1
मैं हाल ही में एक परियोजना के लिए इस समाधान का उपयोग करते हुए एक समस्या में भाग गया, क्योंकि मूल तालिका से सभी सूचियों को इतिहास तालिका में कैसे कॉपी किया जाता है (कैसे बनाने के लिए ... सारणी .... काम करता है)। हिस्ट्री टेबल पर यूनिक इंडेक्स होने के बाद AFSERT क्वेरी को AFTER UPDATE ट्रिगर में बारफ कर सकते हैं, इसलिए उन्हें हटाने की जरूरत है। Php स्क्रिप्ट में मेरे पास यह सामान है, मैं नए बनाए गए हिस्ट्री टेबल पर किसी भी अनूठे इंडेक्स के लिए क्वेरी करता हूं ("SHOW INDEX FROM data_table WHERE Key_name! = 'PRIMARY' और Non_unique = 0" के साथ) और फिर उन्हें हटा दें।
क्षणिक बंद

3
यहां हमें हर बार बैकअप टेबल में बार-बार डेटा डाला जा रहा है। यदि हमारे पास एक तालिका में 10 फ़ील्ड हैं और हमने 2 अपडेट किए हैं तो हम बाकी 8 फ़ील्ड के लिए दोहराया डेटा जोड़ रहे हैं। इससे कैसे उबरें?
itzmukeshy7

6
CREATE TABLE MyDB.data_history as select * from MyDB.data limit 0;
एरिक हेस

4
@transientclosure आप इतिहास में अन्य फ़ील्ड्स को कैसे प्रस्तावित करेंगे जो मूल क्वेरी का हिस्सा नहीं थे? उदाहरण के लिए मैं उन परिवर्तनों को ट्रैक करना चाहता हूं जो उन लोगों को बनाते हैं। सम्मिलित करने के लिए इसके पास पहले से ही एक ownerफ़ील्ड है, और अपडेट के लिए मैं एक updatedbyफ़ील्ड जोड़ सकता हूं , लेकिन हटाने के लिए मुझे यकीन नहीं है कि मैं कैसे ट्रिगर के माध्यम से ऐसा कर सकता हूं। data_historyगंदे महसूस करने में उपयोगकर्ता आईडी के साथ पंक्ति को अद्यतन करना : P
हॉर्स

16

आप इसे हल करने के लिए ट्रिगर बना सकते हैं। यहाँ ऐसा करने के लिए एक ट्यूटोरियल है (संग्रहीत लिंक)।

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

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

यह ट्रिगर एक इतिहास तालिका में एक पुराने मान को कॉपी करेगा यदि इसे किसी पंक्ति को संपादित करने पर बदल दिया जाए। Editor IDऔर last modहर बार मूल तालिका में संग्रहीत किए जाने पर कोई भी उस पंक्ति को संपादित करता है; समय उस समय से मेल खाता है जब इसे अपने वर्तमान स्वरूप में बदला गया था।

DROP TRIGGER IF EXISTS history_trigger $$

CREATE TRIGGER history_trigger
BEFORE UPDATE ON clients
    FOR EACH ROW
    BEGIN
        IF OLD.first_name != NEW.first_name
        THEN
                INSERT INTO history_clients
                    (
                        client_id    ,
                        col          ,
                        value        ,
                        user_id      ,
                        edit_time
                    )
                    VALUES
                    (
                        NEW.client_id,
                        'first_name',
                        NEW.first_name,
                        NEW.editor_id,
                        NEW.last_mod
                    );
        END IF;

        IF OLD.last_name != NEW.last_name
        THEN
                INSERT INTO history_clients
                    (
                        client_id    ,
                        col          ,
                        value        ,
                        user_id      ,
                        edit_time
                    )
                    VALUES
                    (
                        NEW.client_id,
                        'last_name',
                        NEW.last_name,
                        NEW.editor_id,
                        NEW.last_mod
                    );
        END IF;

    END;
$$

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


9

यहां बताया गया है कि हमने इसे कैसे हल किया

एक उपयोगकर्ता तालिका इस तरह दिखती थी

Users
-------------------------------------------------
id | name | address | phone | email | created_on | updated_on

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

Users (the data that won't change over time)
-------------
id | name

UserData (the data that can change over time and needs to be tracked)
-------------------------------------------------
id | id_user | revision | city | address | phone | email | created_on
 1 |   1     |    0     | NY   | lake st | 9809  | @long | 2015-10-24 10:24:20
 2 |   1     |    2     | Tokyo| lake st | 9809  | @long | 2015-10-24 10:24:20
 3 |   1     |    3     | Sdny | lake st | 9809  | @long | 2015-10-24 10:24:20
 4 |   2     |    0     | Ankr | lake st | 9809  | @long | 2015-10-24 10:24:20
 5 |   2     |    1     | Lond | lake st | 9809  | @long | 2015-10-24 10:24:20

किसी भी उपयोगकर्ता का वर्तमान पता खोजने के लिए, हम संशोधन DESC और LIMIT 1 के साथ UserData की खोज करते हैं

किसी निश्चित समय के बीच उपयोगकर्ता का पता प्राप्त करने के लिए हम create_on bewteen (date1, date 2) का उपयोग कर सकते हैं


यह एक समाधान है जो मैं करना चाहता हूं लेकिन मैं जानना चाहता हूं कि आप ट्रिगर का उपयोग करके इस तालिका में id_user कैसे डाल सकते हैं?
thecassion

1
क्या हुआ revision=1की id_user=1? पहले मैंने सोचा था कि आपकी गिनती थी, 0,2,3,...लेकिन फिर मैंने देखा कि id_user=2संशोधन की गिनती के लिए है0,1, ...
Pathros 15

1
आप की जरूरत नहीं है idऔर id_userस्तंभों . Just use a group ID of id` (यूजर आईडी) और revision
गजस

6

मारियाडीबी 10.3 के बाद से सिस्टम वर्जनिंग का समर्थन करता है जो कि मानक एसक्यूएल फीचर है जो वास्तव में वही करता है जो आप चाहते हैं: यह टेबल रिकॉर्ड के इतिहास को संग्रहीत करता है और SELECTप्रश्नों के माध्यम से इस तक पहुंच प्रदान करता है । MariaDB MySQL का एक ओपन-डेवलपमेंट फोर्क है। आप इस लिंक के माध्यम से इसके सिस्टम संस्करण पर और अधिक जानकारी प्राप्त कर सकते हैं:

https://mariadb.com/kb/en/library/system-versioned-tables/


कृपया ऊपर दिए गए लिंक से निम्नलिखित पर ध्यान दें: "mysqldump संस्करण तालिकाओं से ऐतिहासिक पंक्तियों को नहीं पढ़ता है, और इसलिए ऐतिहासिक डेटा का बैकअप नहीं लिया जाएगा। इसके अलावा, टाइमस्टैम्प की पुनर्स्थापना संभव नहीं होगी क्योंकि वे सम्मिलित नहीं कर सकते हैं / एक उपयोगकर्ता।"
डैनियल

4

बस बिन लॉग फाइल का उपयोग क्यों नहीं किया जाता है? यदि प्रतिकृति मैसकल सर्वर पर सेट है, और बिनल फ़ाइल प्रारूप आरओडब्ल्यू पर सेट है, तो सभी परिवर्तनों को कैप्चर किया जा सकता है।

एक अच्छा अजगर पुस्तकालय जिसे नोपेले कहा जाता है, का उपयोग किया जा सकता है। अधिक जानकारी यहाँ


2
यदि आपके पास प्रतिकृति की आवश्यकता नहीं है, तो भी Binlog का उपयोग किया जा सकता है। Binlog में कई लाभकारी उपयोग के मामले हैं। प्रतिकृति शायद सबसे आम उपयोग मामला है, लेकिन इसे बैकअप और ऑडिट इतिहास के लिए भी बदला जा सकता है, जैसा कि यहां बताया गया है।
वेबहॉलिक

3

बस मेरे 2 सेंट। मैं एक समाधान बनाऊंगा जो बिल्कुल बदल गया, जो क्षणिक समाधान के समान है।

मेरा परिवर्तन आसान होगा:

DateTime | WhoChanged | TableName | Action | ID |FieldName | OldValue

1) जब एक पूरी पंक्ति को मुख्य तालिका में बदल दिया जाता है, तो बहुत सारी प्रविष्टियां इस तालिका में जाएंगी, लेकिन जो बहुत संभावना नहीं है, इसलिए एक बड़ी समस्या नहीं है (लोग आमतौर पर केवल एक चीज बदल रहे हैं) 2) OldVaue (और NewValue यदि आप चाहते हैं) किसी भी तरह के महाकाव्य "anytype" होना चाहिए क्योंकि यह कोई भी डेटा हो सकता है, RAW प्रकारों के साथ ऐसा करने का एक तरीका हो सकता है या केवल JSON स्ट्रिंग्स का उपयोग अंदर और बाहर बदलने के लिए किया जा सकता है।

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

केवल पंक्ति ID बनाने और हटाने के लिए, कोई फ़ील्ड आवश्यक नहीं है। मुख्य टेबल पर एक ध्वज को हटाने पर (सक्रिय?) अच्छा होगा।


0

ऐसा करने का सीधा तरीका तालिकाओं पर ट्रिगर बनाना है। कुछ शर्तों या मानचित्रण विधियों को सेट करें। जब अपडेट या डिलीट होता है, तो यह स्वचालित रूप से 'परिवर्तन' तालिका में सम्मिलित हो जाएगा।

लेकिन सबसे बड़ा हिस्सा क्या है अगर हमें बहुत सारे कॉलम और बहुत सारी टेबल मिल गई। हमें हर कॉलम का नाम हर टेबल पर लिखना होगा। जाहिर है, यह समय की बर्बादी है।

इसे और अधिक भव्य रूप से संभालने के लिए, हम स्तंभों के नाम को पुनः प्राप्त करने के लिए कुछ प्रक्रियाएँ या कार्य बना सकते हैं।

हम इसे करने के लिए बस 3-पार्ट टूल का भी उपयोग कर सकते हैं। यहाँ, मैं एक java प्रोग्राम Mysql Tracker लिखता हूँ


मैं आपके मैसकल ट्रैकर का उपयोग कैसे कर सकता हूं?
वेबचुन

1
1. सुनिश्चित करें कि आपके पास प्रत्येक तालिका में प्राथमिक कुंजी के रूप में एक आईडी कॉलम है। 2. जावा फ़ाइल को स्थानीय (या आईडीई) पर कॉपी करें। अपने डेटाबेस कॉन्फ़िगरेशन और संरचना के अनुसार, लाइक्स को आयात करें और स्टेटिक चर को 9-15 से संपादित करें। 4. जावा फ़ाइल को पार्स और रन करें 5. कंसोल लॉग को कॉपी करें और इसे
मैसकल

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