वैसे आप जानते हैं कि यह एक गैर तुच्छ समस्या है। मैंने पिछले साल एक व्यावसायिक ऐप के लिए इसे पूरा करने के लिए एक पुस्तकालय लिखा था और इसे उस स्थान तक पहुँचाने में लगभग 6 महीने लगे जहाँ मैं इससे खुश था।
फ़ायरवॉल और समर्थन मुद्दों से बचने के लिए पोर्ट 80 और HTTP (टीसीपी/आईपी) का उपयोग करने के तर्क को छोड़कर, आपको एक प्रोटोकॉल डिजाइन करने की आवश्यकता है। चूंकि मेरी परियोजना बहुत डेटा गहन थी, इसलिए मैं एक बाइनरी प्रोटोकॉल (फूला हुआ एक्सएमएल के बजाए) के साथ गया जो किसी भी डेटा को संभाल सकता था। मैं यह भी चाहता था कि यह द्वि-दिशात्मक हो ताकि मैं डेटा सम्मिलित करने के साथ-साथ अनुरोधों को निष्पादित कर सकूं। मैंने सर्वर पर CGI/FastCGI का उपयोग किया है।
मेरे द्वारा डिज़ाइन किया गया बाइनरी प्रोटोकॉल काफी सरल (हमेशा बेहतर) है और बड़े स्थानान्तरण को उपयोगकर्ता परिभाषित आकार के टुकड़ों में तोड़ देता है (लगभग 600k अच्छा लगता है)। प्रत्येक खंड में डेटा के बाद एक शीर्षलेख होता है।
यद्यपि इस प्रोटोकॉल का उपयोग किसी भी प्रकार के डेटा को प्रसारित करने के लिए किया जा सकता है, आमतौर पर इसका उपयोग डेटाबेस शैली डेटा के लिए किया जाता है जैसा कि आपके प्रश्न से पता चलता है। इसे समायोजित करने के लिए, मैंने डिजाइन के लिए पंक्तियों/स्तंभों के दृष्टिकोण का उपयोग करने का निर्णय लिया। डेटा को एक समय में एक पंक्ति में संग्रहीत किया जाता है, जिसका अर्थ है कि प्रत्येक कॉलम पंक्ति एक के लिए संग्रहीत किया जाता है, फिर पंक्ति 2 के लिए सभी कॉलम ... पंक्ति n।
एकल कॉलम डेटा का प्रारूप है:
' Col1Type 1Bytes - BYTE ' Data Type (REMSQL_TEXT etc)
' Col1Len 4Bytes - DWORD ' Length in bytes the Column Data - up to 4.2GB
' Col1Data nBytes - BYTE ' String data
(सी में, एक बाइट चार्ज है)
इसका मतलब है कि प्रत्येक कॉलम में डेटा टाइप डिस्क्रिप्टर होता है। सभी डेटाटाइप के साथ प्रदर्शित किया जा सकता है:
REMSQL_NONE = 0 ' DataType undefined
REMSQL_QUAD = 1 ' 64-bit signed integer
REMSQL_DBLE = 2 ' 64-bit IEEE floating point number
REMSQL_TEXT = 3 ' STRING - (CHAR) string of Ascii Bytes
REMSQL_BLOB = 4 ' BLOB - (CHAR) string of Binary Bytes
REMSQL_NULL = 5 ' NULL - Empty Column
ये डेटा प्रकार SQLite मौलिक डेटा प्रकारों के साथ सह-संक्रमित होते हैं और संख्यात्मक रूप से SQL3 मौलिक डेटाटाइप गणना के बराबर होते हैं।
इस डिज़ाइन में, यदि कोई फ़ील्ड खाली (NULL) है तो आपने उसे स्टोर करने के लिए केवल 5 बाइट्स लिए हैं। उदाहरण के लिए, यदि किसी फ़ील्ड में 200 बाइट्स टेक्स्ट हैं, तो उसे स्टोर करने में केवल 205 बाइट्स लगते हैं। डेटा को पार्स करने में बड़ा लाभ है क्योंकि कुछ टर्मिनेटिंग कैरेक्टर खोजने के लिए सभी 200 बाइट्स को पढ़े बिना कॉलम को स्किप किया जा सकता है।
चंक हेडर में पंक्तियों की संख्या, कॉलम की संख्या, कुल बाइट्स आदि जैसी चीजें होनी चाहिए। यदि आप DWORDs (अहस्ताक्षरित 64 बिट पूर्णांक) का उपयोग करते हैं तो एक चंक के लिए सैद्धांतिक सीमा 4.2gigs है जो स्थानीय नेटवर्क ट्रांसमिशन के लिए भी पर्याप्त होनी चाहिए।
कार्यान्वयन के लिए इस कार्यक्षमता के लिए SQLite/MYSQL रैपर लिखने की आवश्यकता है। मैं विशेष रूप से बाइनरी प्रोटोकॉल का उपयोग करता हूं, जिसमें थोड़ा समय लगता है, लेकिन आपको अनिवार्य रूप से निम्नलिखित कार्यों की आवश्यकता होती है:क्लाइंट साइड:SendRequest () - अनुरोध भेजता है, प्रतिक्रिया की प्रतीक्षा करता है
सर्वर साइड:ProcessRequest () - अनुरोध प्राप्त करता है, इसे संसाधित करता है और प्रतिक्रिया देता है
मेरे मामले में, प्रतिक्रिया !00MB डेटा या अधिक हो सकती है। मैं MySQL से पूरा डेटा सेट पुनर्प्राप्त करता हूं और इसे सर्वर पर डिस्क पर सहेजता हूं। फिर मैं एक खाली हिस्सा लौटाता हूं जिसमें डेटा सेट मेट्रिक्स होता है। क्लाइंट तब एक-एक करके, 600k के विखंडू में सेट किए गए डेटा का अनुरोध करता है। यदि कनेक्शन खो जाता है, तो यह वहीं से शुरू होता है जहां से छोड़ा था।
अंत में, डेटा सेट ज्यादातर टेक्स्ट (नाम पते आदि) था जो संपीड़न के लिए परिपक्व था। इस मामले में सुरक्षा एक बहुत बड़ा मुद्दा था इसलिए एन्क्रिप्शन आवश्यक था। इसे लागू करने के लिए थोड़ा और जटिल हो जाता है, लेकिन मूल रूप से आप पूरे खंड, पैड को उस लंबाई तक संपीड़ित करते हैं जो ब्लॉक सिफर का एक बहु है BLOCKSIZE और इसे एन्क्रिप्ट करें।
इस सब की प्रक्रिया में मैं एक बहुत तेज़ स्ट्रिंग बिल्डर क्लास लिखता हूं, एएसएम में एईएस एन्क्रिप्शन का कार्यान्वयन, और एक संपूर्ण फास्टसीजीआई लाइब्रेरी (www.coastrd.com)
तो जैसा कि मैंने कहा, गैर तुच्छ। मैं जल्द ही इस पुस्तकालय को उपलब्ध कराऊंगा। अगर आप इसे देखना चाहते हैं, तो मुझे ईमेल करें।
एक बार जब आपके पास संचार लिखा होता है तो आप सिंक्रनाइज़ेशन को डिज़ाइन करना शुरू कर सकते हैं। मैं या तो प्रत्येक रिकॉर्ड के लिए हैश का उपयोग करता हूं, या एक साधारण बूलियन ध्वज का उपयोग करता हूं। अगर सर्वर पर कुछ भी बदलता है, तो बस पूरा रिकॉर्ड भेजें और इसे क्लाइंट साइड पर ओवरराइट करें (यह मानते हुए कि आप क्लाइंट को सिंक्रोनाइज़ करने की कोशिश कर रहे हैं...)
अगर आप अपना खुद का लिखते हैं, तो कृपया अपने अनुभव के बारे में यहां वापस पोस्ट करें!
पुनश्च. अधिक खोज अनुकूल होने के लिए शीर्षक बदलने पर विचार करें.. शायद कुछ ऐसा:
"एक SQLite क्लाइंट डेटाबेस को एक MySQL सर्वर डेटाबेस के साथ सिंक्रनाइज़ करना"