शानदार सवाल। मैं इसके तीन दृष्टिकोणों के बारे में जानता हूं, जिन्हें मैं नीचे सूचीबद्ध करूंगा।
मैं इसके लिए थोड़ा अलग उदाहरण लेगा, अधिकतर क्योंकि यह मुझे स्पष्टीकरण में अधिक ठोस शब्दों का उपयोग करने की अनुमति देता है।
कहें कि हमारे पास चैट एप्लिकेशन है, जहां हम दो इकाइयों को स्टोर करते हैं: संदेश और उपयोगकर्ता। स्क्रीन में जहां हम संदेश दिखाते हैं, हम उपयोगकर्ता का नाम भी दिखाते हैं। इसलिए पढ़ने की संख्या को कम करने के लिए, हम प्रत्येक चैट संदेश के साथ उपयोगकर्ता का नाम भी स्टोर करते हैं।
users
so:209103
name: "Frank van Puffelen"
location: "San Francisco, CA"
questionCount: 12
so:3648524
name: "legolandbridge"
location: "London, Prague, Barcelona"
questionCount: 4
messages
-Jabhsay3487
message: "How to write denormalized data in Firebase"
user: so:3648524
username: "legolandbridge"
-Jabhsay3591
message: "Great question."
user: so:209103
username: "Frank van Puffelen"
-Jabhsay3595
message: "I know of three approaches, which I'll list below."
user: so:209103
username: "Frank van Puffelen"
तो हम users
नोड में उपयोगकर्ता के प्रोफ़ाइल के प्राथमिक प्रतिलिपि संग्रहीत। संदेश में हम uid
(इसलिए: 20 9 103 और इसलिए: 3648524) स्टोर करते हैं ताकि हम उपयोगकर्ता को देख सकें। लेकिन हम भी संदेशों में उपयोगकर्ता का नाम संग्रहीत करते हैं, ताकि जब हम संदेशों की सूची प्रदर्शित करना चाहते हैं तो हमें प्रत्येक उपयोगकर्ता के लिए इसे देखना नहीं है।
तो अब जब मैं चैट सेवा पर प्रोफाइल पेज पर जाता हूं और "फ्रैंक वैन पफेलन" से अपना नाम बदलता हूं तो बस "पुफ" में बदल जाता है।
लेन-देन संबंधी अद्यतन
एक लेन-देन संबंधी अद्यतन प्रदर्शन एक है कि शायद शुरू में सबसे डेवलपर्स के मन में पॉप है। हम हमेशा संबंधित प्रोफाइल में name
से मेल खाने के लिए संदेशों में username
संदेश चाहते हैं।
बहुपथ का उपयोग करते हुए लिखते हैं (20,150,925 पर जोड़ा)
Firebase 2.3 (JavaScript) और 2.4 (Android और iOS के लिए), आप एक ही बहुपथ अद्यतन का उपयोग करके काफी आसानी से परमाणु अपडेट प्राप्त कर सकते हैं के बाद से:
function renameUser(ref, uid, name) {
var updates = {}; // all paths to be updated and their new values
updates['users/'+uid+'/name'] = name;
var query = ref.child('messages').orderByChild('user').equalTo(uid);
query.once('value', function(snapshot) {
snapshot.forEach(function(messageSnapshot) {
updates['messages/'+messageSnapshot.key()+'/username'] = name;
})
ref.update(updates);
});
}
यह फ़ायरबेस में एक एकल अपडेट कमांड भेजेगा जो उपयोगकर्ता के नाम को उनके प्रोफ़ाइल में और प्रत्येक संदेश में अपडेट करेगा।
पिछला परमाणु दृष्टिकोण
तो जब उपयोगकर्ता परिवर्तन उनके प्रोफ़ाइल में name
है:
var ref = new Firebase('https://mychat.firebaseio.com/');
var uid = "so:209103";
var nameInProfileRef = ref.child('users').child(uid).child('name');
nameInProfileRef.transaction(function(currentName) {
return "puf";
}, function(error, committed, snapshot) {
if (error) {
console.log('Transaction failed abnormally!', error);
} else if (!committed) {
console.log('Transaction aborted by our code.');
} else {
console.log('Name updated in profile, now update it in the messages');
var query = ref.child('messages').orderByChild('user').equalTo(uid);
query.on('child_added', function(messageSnapshot) {
messageSnapshot.ref().update({ username: "puf" });
});
}
console.log("Wilma's data: ", snapshot.val());
}, false /* don't apply the change locally */);
सुंदर शामिल और चतुर पाठक है कि मैं संदेशों की हैंडलिंग में धोखा देखेंगे। पहली धोखा यह है कि श्रोता के लिए मैंने कभी भी off
पर कॉल नहीं किया, लेकिन मैं लेनदेन का भी उपयोग नहीं करता हूं।
हम सुरक्षित रूप से ग्राहक से आपरेशन के इस प्रकार करना चाहते हैं, तो हम आवश्यकता होगी:
- सुरक्षा नियम है कि दोनों स्थानों मैच में नाम हैं। लेकिन नियमों को बदलते समय नियमों को अस्थायी रूप से भिन्न होने के लिए पर्याप्त लचीलापन की अनुमति देने की आवश्यकता है। तो यह एक बहुत दर्दनाक दो चरण प्रतिबद्ध योजना में बदल जाता है।
- परिवर्तन
so:209103
null
करने से संदेशों के लिए सभी username
क्षेत्रों (कुछ जादू मूल्य)
- परिवर्तन
so:209103
कि है puf
को null
द्वारा 'PUF'
- परिवर्तन
username
हर संदेश में करने के लिए उपयोगकर्ता so:209103
की name
।
- उस क्वेरी को दो स्थितियों में से
and
की आवश्यकता होती है, जो Firebase क्वेरी का समर्थन नहीं करते हैं। तो हम एक अतिरिक्त संपत्ति uid_plus_name
(मूल्य so:209103_puf
के साथ) के साथ समाप्त हो जाएंगे, जिसे हम पूछ सकते हैं।
- क्लाइंट-साइड कोड जो इन सभी संक्रमणों को लेनदेन से संभालता है।
इस प्रकार का दृष्टिकोण मेरे सिर को चोट पहुंचाता है। और आमतौर पर इसका मतलब है कि मैं कुछ गलत कर रहा हूं। लेकिन यहां तक कि यदि यह सही दृष्टिकोण है, तो सिर के साथ दर्द होता है, मैं कोडिंग गलतियों को करने की अधिक संभावना रखता हूं। इसलिए मैं एक सरल समाधान की तलाश करना पसंद करता हूं।
अंततः स्थिरता
अद्यतन (20,150,925): Firebase अनेक पथों को परमाणु राईट अनुमति देने के लिए एक सुविधा का विमोचन किया। यह नीचे दृष्टिकोण के समान काम करता है, लेकिन एक ही कमांड के साथ। यह कैसे काम करता है पढ़ने के लिए उपरोक्त अद्यतन अनुभाग देखें। 209,103 और हर संदेश में:
दूसरा दृष्टिकोण उपयोगकर्ता कार्रवाई ("मैं 'PUF' के लिए मेरे नाम बदलना चाहते हैं") है कि कार्रवाई के निहितार्थ से बंटवारे पर निर्भर करता है ("हम प्रोफ़ाइल इसलिए में नाम को अपडेट करना कि user = so:209103
है)
मैं एक स्क्रिप्ट है कि हम एक सर्वर पर चलने में नाम बदलने को संभालने था मुख्य विधि कुछ इस तरह होगा:।।
function renameUser(ref, uid, name) {
ref.child('users').child(uid).update({ name: name });
var query = ref.child('messages').orderByChild('user').equalTo(uid);
query.once('value', function(snapshot) {
snapshot.forEach(function(messageSnapshot) {
messageSnapshot.update({ username: name });
})
});
}
एक बार फिर मैं यहाँ कुछ शॉर्टकट ले, जैसे कि once('value'
(जो आमतौर पर फायरबेस के साथ इष्टतम प्रदर्शन के लिए एक बुरा विचार है) का उपयोग करना। लेकिन कुल मिलाकर दृष्टिकोण सरल है, वें एक ही समय में सभी डेटा पूरी तरह अद्यतन नहीं होने की लागत। लेकिन आखिर में संदेशों को नए मूल्य से मेल खाने के लिए अपडेट किया जाएगा।
सभी का सबसे सरल
देखभाल नहीं तीसरे दृष्टिकोण है: कई मामलों में आप वास्तव में डुप्लिकेट किए गए डेटा को अद्यतन करने की जरूरत नहीं है। उदाहरण में हमने यहां उपयोग किया है, आप कह सकते हैं कि प्रत्येक संदेश ने उस नाम को रिकॉर्ड किया जैसा मैंने उस समय उपयोग किया था। मैंने अभी तक अपना नाम नहीं बदला है, इसलिए यह समझ में आता है कि पुराने संदेश उस समय दिखाए गए नाम को दिखाते हैं। यह कई मामलों में लागू होता है जहां द्वितीयक डेटा प्रकृति में लेनदेन होता है। यह हर जगह लागू नहीं होता है, लेकिन जहां यह "देखभाल नहीं" लागू होता है, वह सभी का सबसे आसान तरीका है।
सारांश
जबकि ऊपर कैसे आप इस समस्या को हल कर सकता है की सिर्फ व्यापक वर्णन दिए गए हैं और वे निश्चित रूप से पूरा नहीं कर रहे हैं, मुझे लगता है कि हर बार जब मैं डुप्लिकेट डेटा बाहर प्रशंसक की जरूरत है यह इन बुनियादी से एक के लिए वापस आता है दृष्टिकोण।
* मैं नीचे एक उचित उत्तर लिखूंगा। * वह पहला वाक्य मुझे खुश करता है। क्या आप इसे जन्मदिन की पार्टियों पर दोहरा सकते हैं? खासकर जब देव दोस्त मौजूद हैं। :-) –
यह प्रासंगिक लगता है, भी .. https://stackoverflow.com/questions/47334382 – Fattie