मैंने लगभग 8 साल पहले एक ऐप के लिए इस तरह की एक प्रणाली बनाई थी, और मैं कुछ तरीके साझा कर सकता हूं जो कि विकसित हो गए हैं जैसे कि ऐप का उपयोग बढ़ा है।
मैंने किसी भी डिवाइस से "इतिहास" तालिका में हर परिवर्तन (सम्मिलित करें, अपडेट या हटाएं) को लॉग इन करके शुरू किया। इसलिए, यदि, उदाहरण के लिए, कोई व्यक्ति "संपर्क" तालिका में अपना फोन नंबर बदलता है, तो सिस्टम contact.phone फ़ील्ड को संपादित करेगा, और एक्शन = अपडेट, फ़ील्ड = फोन, रिकॉर्ड = [संपर्क आईडी] के साथ एक इतिहास रिकॉर्ड भी जोड़ देगा, मूल्य = [नया फोन नंबर]। फिर जब भी कोई डिवाइस सिंक करता है, तो वह आखिरी सिंक के बाद से हिस्ट्री आइटम को डाउनलोड करता है और उन्हें अपने स्थानीय डेटाबेस पर लागू करता है। यह ऊपर वर्णित "लेनदेन प्रतिकृति" पैटर्न की तरह लगता है।
एक मुद्दा आईडी को विशिष्ट बनाए रखना है, जब विभिन्न उपकरणों पर आइटम बनाए जा सकते हैं। जब मैंने इसे शुरू किया था तो मुझे यूयूआईडी के बारे में पता नहीं था, इसलिए मैंने ऑटो-इन्क्रिमेंटिंग आईडी का उपयोग किया और कुछ जटिल कोड लिखे, जो उपकरणों से अपलोड की गई नई आईडी की जांच करने के लिए केंद्रीय सर्वर पर चलता है, यदि कोई विरोधाभास है, तो उन्हें एक अद्वितीय आईडी में बदल दें। अपने स्थानीय डेटाबेस में आईडी को बदलने के लिए स्रोत डिवाइस बताएं। बस नए रिकॉर्ड की आईडी बदलना इतना बुरा नहीं था, लेकिन अगर मैं बनाता हूं, उदाहरण के लिए, संपर्क तालिका में एक नया आइटम, तो घटना तालिका में एक नया संबंधित आइटम बनाएं, अब मेरे पास विदेशी चाबियाँ हैं जो मुझे भी चाहिए जाँच करें और अद्यतन करें।
आखिरकार मुझे पता चला कि यूयूआईडी इससे बच सकते हैं, लेकिन तब तक मेरा डेटाबेस बहुत बड़ा हो रहा था और मुझे डर था कि एक पूर्ण यूयूआईडी कार्यान्वयन एक प्रदर्शन समस्या पैदा करेगा। इसलिए पूर्ण यूयूआईडी का उपयोग करने के बजाय, मैंने आईडी के रूप में बेतरतीब ढंग से उत्पन्न, 8 वर्ण अल्फ़ान्यूमेरिक कुंजियों का उपयोग करना शुरू कर दिया और संघर्षों को संभालने के लिए मैंने अपना मौजूदा कोड छोड़ दिया। मेरी वर्तमान 8-वर्ण कुंजियों और UUID के 36 वर्णों के बीच कहीं एक ऐसा मधुर स्थान होना चाहिए जो अनावश्यक रूप से प्रस्फुटित हुए बिना संघर्षों को समाप्त कर दे, लेकिन चूँकि मेरे पास पहले से ही संघर्ष समाधान कोड है, इसलिए इसका प्रयोग करना प्राथमिकता नहीं है। ।
अगली समस्या यह थी कि हिस्ट्री टेबल पूरे बाकी डेटाबेस से लगभग 10 गुना बड़ी थी। यह भंडारण को महंगा बनाता है, और इतिहास की मेज पर कोई रखरखाव दर्दनाक हो सकता है। उस पूरी तालिका को रखने से उपयोगकर्ता किसी भी पिछले परिवर्तन को वापस ले सकते हैं, लेकिन यह ओवरकिल की तरह लगने लगा। इसलिए मैंने एक समन्वयन प्रक्रिया में एक रूटीन जोड़ा जहां अगर इतिहास आइटम जिसे अंतिम रूप से डाउनलोड किया गया डिवाइस अब इतिहास तालिका में मौजूद नहीं है, तो सर्वर इसे हाल के इतिहास आइटम नहीं देता है, बल्कि इसके लिए एक फ़ाइल देता है जिसमें सभी डेटा होते हैं वह खाता। फिर मैंने 90 दिनों से अधिक पुराने इतिहास के आइटम को हटाने के लिए एक क्रोनजॉब जोड़ा। इसका मतलब है कि उपयोगकर्ता अभी भी 90 दिनों से कम पुराने परिवर्तनों को वापस ले सकते हैं, और यदि वे हर 90 दिनों में कम से कम एक बार सिंक करते हैं, तो अपडेट पहले की तरह ही वृद्धिशील होंगे। लेकिन अगर वे 90 दिनों से अधिक समय तक प्रतीक्षा करें,
उस परिवर्तन ने इतिहास तालिका का आकार लगभग 90% कम कर दिया है, इसलिए अब इतिहास तालिका बनाए रखने से डेटाबेस केवल दस गुना बड़ा होने के बजाय दोगुना हो जाता है। इस प्रणाली का एक अन्य लाभ यह है कि यदि आवश्यक हो तो सिंक्रनाइज़ेशन अभी भी इतिहास तालिका के बिना काम कर सकता है - जैसे कि अगर मुझे कुछ रखरखाव करने की आवश्यकता थी जो इसे अस्थायी रूप से ले गया। या मैं अलग-अलग मूल्य बिंदुओं पर खातों के लिए अलग-अलग रोलबैक समय अवधि की पेशकश कर सकता हूं। और अगर डाउनलोड करने के लिए 90 दिनों से अधिक के परिवर्तन हैं, तो पूर्ण फ़ाइल आमतौर पर वृद्धिशील प्रारूप की तुलना में अधिक कुशल है।
अगर मैं आज से शुरू कर रहा था, तो मैं आईडी संघर्ष जाँच को छोड़ दूंगा और सिर्फ एक प्रमुख लंबाई के लिए लक्ष्य रखूँगा जो कि संघर्ष को खत्म करने के लिए पर्याप्त है, किसी प्रकार की त्रुटि की जाँच के लिए। लेकिन इतिहास तालिका और हाल के अपडेट के लिए वृद्धिशील डाउनलोडों का संयोजन या जरूरत पड़ने पर एक पूर्ण डाउनलोड अच्छी तरह से काम कर रहा है।