एक पहले से लोड की गई वस्तु के सीधे डंप को कैशिंग करने के लिए, हाँ, आप कुछ भी नहीं या अगले-कुछ भी नहीं हासिल करते हैं। यही नहीं उन उदाहरणों का वर्णन किया जा रहा है - वे एक पदानुक्रम का वर्णन कर रहे हैं, जहां कुछ कम करने के लिए किसी भी परिवर्तन को भी पदानुक्रम में उच्चतर सब कुछ के लिए एक अद्यतन ट्रिगर करना चाहिए।
37signals ब्लॉग से पहला उदाहरण, Project -> Todolist -> Todoपदानुक्रम के रूप में उपयोग करता है। एक आबाद उदाहरण इस तरह दिख सकता है:
Project: Foo (last_modified: 2014-05-10)
Todolist: Bar1 (last_modified: 2014-05-10)
Todo: Bang1 (last_modified: 2014-05-09)
Todo: Bang2 (last_modified: 2014-05-09)
Todolist: Bar2 (last_modified: 2014-04-01)
Todo: Bang3 (last_modified: 2014-04-01)
Todo: Bang4 (last_modified: 2014-04-01)
तो, चलिए Bang3अपडेट किया गया था। इसके सभी अभिभावक भी अपडेट रहें:
Project: Foo (last_modified: 2014-05-16)
Todolist: Bar2 (last_modified: 2014-05-16)
Todo: Bang3 (last_modified: 2014-05-16)
फिर जब रेंडर करने का समय आता है, Projectतो डेटाबेस से लोड करना मूल रूप से अपरिहार्य है। आपको शुरू करने के लिए एक बिंदु की आवश्यकता है। हालाँकि, क्योंकि यह अपने सभी बच्चोंlast_modified का एक संकेतक है , यही कारण है कि आप बच्चों को लोड करने के प्रयास से पहले कैश कुंजी के रूप में उपयोग करते हैं।
जबकि ब्लॉग पोस्ट अलग टेम्प्लेट का उपयोग करते हैं, मैं उन्हें एक में एक साथ गांठ करने वाला हूं। उम्मीद है कि एक ही स्थान पर पूरी बातचीत देखने से यह थोड़ा स्पष्ट हो जाएगा।
तो, Django टेम्पलेट कुछ इस तरह दिख सकता है:
{% cache 9999 project project.cache_key %}
<h2>{{ project.name }}<h2>
<div>
{% for list in project.todolist.all %}
{% cache 9999 todolist list.cache_key %}
<ul>
{% for todo in list.todos.all %}
<li>{{ todo.body }}</li>
{% endfor %}
</ul>
{% endcache %}
{% endfor %}
</div>
{% endcache %}
कहते हैं कि हम एक ऐसी परियोजना से गुजरते हैं, जो cache_keyअभी भी कैश में मौजूद है। क्योंकि हम माता-पिता से संबंधित सभी वस्तुओं में परिवर्तन का प्रचार करते हैं, यह तथ्य कि विशेष कुंजी अभी भी मौजूद है मतलब है कि संपूर्ण प्रदान की गई सामग्री को कैश से खींचा जा सकता है।
यदि वह विशेष प्रोजेक्ट अभी-अभी अपडेट किया गया है - उदाहरण के लिए, जैसा कि Fooऊपर दिया गया है - तो उसे अपने बच्चों को प्रस्तुत करना होगा, और उसके बाद ही वह उस प्रोजेक्ट के लिए सभी टॉडोलिस्ट के लिए क्वेरी चलाएगा। इसी तरह एक विशिष्ट टोडोलिस्ट के लिए - यदि उस सूची का cache_key मौजूद है, तो उसके अंदर के टॉडोस नहीं बदले हैं, और पूरी चीज को कैश से खींचा जा सकता है।
यह भी ध्यान दें कि मैं todo.cache_keyइस टेम्पलेट का उपयोग कैसे नहीं कर रहा हूं । यह इसके लायक नहीं है, जैसा कि आप सवाल में कहते हैं, bodyडेटाबेस से पहले ही खींच लिया गया है। हालाँकि, डेटाबेस हिट एकमात्र कारण नहीं है जिससे आप कुछ कैश कर सकते हैं। उदाहरण के लिए, कच्चे मार्कअप टेक्स्ट (जैसे कि हम StackExchange पर प्रश्न / उत्तर बॉक्स में क्या टाइप करते हैं) और इसे HTML में कनवर्ट करने में पर्याप्त समय लग सकता है जिससे परिणाम को कैशिंग करना अधिक कुशल होगा।
यदि ऐसा था, तो टेम्प्लेट में आंतरिक लूप इस तरह दिख सकता है:
{% for todo in list.todos.all %}
{% cache 9999 todo todo.cache_key %}
<li>{{ todo.body|expensive_markup_parser }}</li>
{% endcache %}
{% endfor %}
तो सब कुछ एक साथ खींचने के लिए, आइए इस उत्तर के शीर्ष पर अपने मूल डेटा पर वापस जाएं। यदि हम मान लें:
- सभी वस्तुओं को उनके मूल राज्य में कैश किया गया था
Bang3 बस अद्यतन किया गया था
- हम संशोधित टेम्पलेट प्रदान कर रहे हैं (सहित
expensive_markup_parser)
फिर यह है कि सब कुछ कैसे लोड किया जाएगा:
Foo डेटाबेस से पुनर्प्राप्त किया जाता है
Foo.cache_key (2014-05-16) कैश में मौजूद नहीं है
Foo.todolists.all()क्वियर है: Bar1और Bar2डेटाबेस से पुनर्प्राप्त किया जाता है
Bar1.cache_key(2014-05-10) कैश में पहले से मौजूद है ; इसे पुनः प्राप्त और आउटपुट करें
Bar2.cache_key (2014-05-16) कैश में मौजूद नहीं है
Bar2.todos.all()क्वियर है: Bang3और Bang4डेटाबेस से पुनर्प्राप्त किया जाता है
Bang3.cache_key (2014-05-16) कैश में मौजूद नहीं है
{{ Bang3.body|expensive_markup_parser }} प्रस्तुत है
Bang4.cache_key(2014-04-01) पहले से ही कैश में मौजूद है ; इसे पुनः प्राप्त और आउटपुट करें
इस छोटे उदाहरण में कैश से बचत हैं:
- डेटाबेस हिट से बचा गया:
Bar1.todos.all()
expensive_markup_parserबचा 3 बार: Bang1, Bang2, औरBang4
और निश्चित रूप से, अगली बार जब यह देखा Foo.cache_keyजाएगा, तो मिल जाएगा, इसलिए प्रदान करने की एकमात्र लागत Fooडेटाबेस से अकेले पुनर्प्राप्त कर रही है और कैश क्वेरी कर रही है।