मोबाइल क्लाइंट और सर्वर के बीच संदर्भात्मक अखंडता बनाए रखना


21

इसलिए मेरे पास अपेक्षाकृत सरल प्रणाली है। एक मोबाइल क्लाइंट एक sqlite डेटाबेस में रिकॉर्ड बनाता है जिसे मैं एक दूरस्थ SQL सर्वर के साथ समन्वयित करना चाहता हूं (जिसे अन्य क्लाइंट क्लाइंट के साथ साझा किया जाता है) । इसलिए जब मैं फोन के साइक्लाइट टेबल में एक नया रिकॉर्ड बनाता हूं, तो मैं उस परिवर्तन को एक RESTful API के माध्यम से अपनी दूरस्थ सेवा में धकेल देता हूं। मुझे जो समस्या हो रही है, वह यह है कि मैं प्राथमिक कुंजियों का आदेश कैसे दे सकता हूं ताकि डेटा में टकराव न हो (अर्थात फोन में एक रिकॉर्ड में प्राथमिक कुंजी सर्वर पर पूरी तरह से अलग रिकॉर्ड के समान है)। क्लाइंट पर रिकॉर्ड को संदर्भित करने के लिए और सर्वर पर समान रिकॉर्ड को संदर्भित करने के लिए सामान्य "सबसे अच्छा अभ्यास क्या है?"


1
अति-अभिमानी विचार, यह होगा कि क्लाइंट वेब सर्वर के लिए कैश के रूप में कार्य करता है, क्लाइंट में परिवर्तन होने के साथ, फिर वेब सर्वर पर धकेल दिया जाता है
जोकोर्टोपस्सी

जवाबों:


22

सामान्य अभ्यास के साथ अपने डेटाबेस की संरचना करने के है uniqueidentifierकुंजी (कभी कभी UUIDs या GUIDs)। टकराव के यथार्थवादी डर के बिना आप उन्हें दो स्थानों पर बना सकते हैं।

अगला, आपके मोबाइल ऐप को नई पंक्तियां बनाने से पहले सर्वर से "तथ्य" तालिकाओं को सिंक करने की आवश्यकता है। जब आप नई पंक्तियाँ बनाते हैं, तो आप इसे स्थानीय रूप से करते हैं, और जब आप फिर से सिंक करते हैं, तो नई पंक्तियाँ सर्वर में जुड़ जाती हैं। आप अपडेट और डिलीट के साथ भी यही काम कर सकते हैं।

आवेषण को ट्रैक करने के लिए आपको अपनी पंक्तियों पर एक निर्मित टाइमस्टैम्प की आवश्यकता होती है। अद्यतनों को ट्रैक करने के लिए आपको अपनी पंक्तियों पर एक LastUpdate टाइमस्टैम्प को ट्रैक करना होगा। डिलीट को ट्रैक करने के लिए आपको एक मकबरे की मेज की जरूरत है।

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

इस तरह की चीज़ को संभालने के लिए चौखटे हैं, जैसे कि माइक्रोसॉफ्ट सिंक फ्रेमवर्क


अभी भी जिंदा सिंक फ्रेमवर्क है
सदाकत

7

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

इसके लिए दो अभ्यास हैं:

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

दूसरा यह है कि आप आईडी निर्माण को इस तरह से वितरित करते हैं कि (आमतौर पर संभावित रूप से) क्लाइंट को बिना टकराव के आईडी बनाने की अनुमति देता है।

उसके लिए, UUIDs पर जाएं - v4 टकराने की काफी संभावना नहीं है।

अन्यथा, कुछ ऐसा विचार करें जो अद्वितीय मोबाइल डिवाइस आईडी को रिकॉर्ड आईडी में रखता है। तो, आपकी रिकॉर्ड आईडी ${imei}-${local sequence number}या कुछ और हो सकता है, जहां IMEI विशिष्टता सुनिश्चित करता है, और स्थानीय अनुक्रम संख्या केवल एक सामान्य अनुक्रमिक डेटाबेस आईडी है।


2

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


0

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

Local Table            Remote Table

_id (used locally)
remote_id ------------- id
name      ------------- name

क्लाइंट एप्लिकेशन में मैं टेबल को _id फ़ील्ड द्वारा लिंक करता हूं, दूरस्थ रूप से मैं डेटा लाने के लिए रिमोट आईडी फ़ील्ड का उपयोग करता हूं, आदि। आदि।

स्थानीय रूप से उदाहरण:

Local Client Table       Local ClientType Table      Local ClientType
                         _id
                         remote_id  
_id -------------------- client_id
remote_id                client_type_id -------------- _id
                                                      remote_id
name                    name                          name

दूर से उदाहरण दें:

Remote Client Table      Remote ClientType Table      Remote ClientType
id -------------------- client_id
                        client_type_id -------------- id
name                    name                          name

यह परिदृश्य, और कोड में किसी भी तार्किक के बिना, डेटा अखंडता विफलताओं का कारण होगा, क्योंकि client_type तालिका स्थानीय या दूरस्थ तालिकाओं में वास्तविक आईडी से मेल नहीं खा सकती है, जब भी एक रिमोट_आईडी उत्पन्न होती है, तो यह क्लाइंट अनुप्रयोगों के लिए एक संकेत देता है। स्थानीय _id क्षेत्र को अद्यतन करने के लिए कहने पर, यह प्रभावित तालिकाओं को अद्यतन करने वाले sqlite में पहले से निर्मित ट्रिगर को आग लगा देता है। http://www.sqlite.org/lang_createtrigger.html

1- रिमोट_ड सर्वर में उत्पन्न होता है

2- क्लाइंट को सिग्नल देता है

3- क्लाइंट अपने _id फील्ड को अपडेट करता है और एक ट्रिगर को फायर करता है जो लोकल टेब को जोड़ने वाली लोकल टेबल को अपडेट करता है

बेशक मैं सिंक्रोनाइज़ेशन में मदद करने के लिए और डुप्लिकेट किए गए सिंक से बचने के लिए एक last_updated फ़ील्ड का भी उपयोग करता हूं।

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