2009-07-08 23 views
14

मैं एक साधारण वेब ऐप विकसित कर रहा हूं, और यह कुछ denormalized डेटा को स्टोर करने के लिए बहुत समझ में आता है।Django में डेटा को denormalize करने का सबसे अच्छा तरीका?

ब्लॉगिंग प्लेटफ़ॉर्म की कल्पना करें जो टिप्पणियों का ट्रैक रखती है, और BlogEntry मॉडल में "टिप्पणी गणना" फ़ील्ड है जिसे मैं अद्यतित रखना चाहता हूं।

ऐसा करने का एक तरीका Django सिग्नल का उपयोग करना होगा।

ऐसा करने का एक और तरीका है सीधे मेरे कोड में हुक डालना होगा जो टिप्पणियों की गणना को बढ़ाने/घटाने के लिए ब्लॉग एंट्री पर कुछ तरीकों को सिंक्रनाइज़ करने के लिए टिप्पणी ऑब्जेक्ट बनाता है और नष्ट करता है।

मुझे लगता है कि सजावटी या कुछ अन्य वूडू के साथ इसे पूरा करने के अन्य पाइथोनिक तरीके हैं।

Django में denormalizing के लिए मानक डिजाइन पैटर्न क्या है? अभ्यास में, क्या आपको त्रुटियों के मामले में स्थिरता जांचकर्ता और डेटा फिक्सर्स भी लिखना होगा?

उत्तर

17

आपके पास Django में प्रबंधक हैं।

एफके रिश्तों को बनाने और बनाए रखने के लिए एक अनुकूलित प्रबंधक का उपयोग करें।

प्रबंधक गणना के अपडेट कर सकते हैं क्योंकि बच्चों के सेट अपडेट किए जाते हैं।

यदि आप अनुकूलित प्रबंधक नहीं बनाना चाहते हैं, तो बस save विधि का विस्तार करें। Denormalizing गणना और रकम के लिए आप जो कुछ भी करना चाहते हैं save में किया जा सकता है।

आपको सिग्नल की आवश्यकता नहीं है। बस save का विस्तार करें।

+0

महान सलाह, मैंने यह भी किया है – kender

+0

मैं इस दृष्टिकोण को भी लेता हूं, अब तक कोई समस्या नहीं है। – Prairiedogg

+4

क्या आप इस शैली के किसी भी अच्छे उदाहरण के बारे में जानते हैं? मुझे आश्चर्य है कि Django दस्तावेज (या Django बुक) में denormalization दृष्टिकोण का उल्लेख नहीं है ... – slacy

-1

क्यों न सिर्फ टिप्पणियों के सेट मिलता है, और तत्वों की संख्या मिल जाए, count() विधि का उपयोग कर:

count = blog_entry.comment_set.count() 

तो फिर तुम अपने खाके में है कि पारित कर सकते हैं।

या, वैकल्पिक, टेम्पलेट अपने आप में, आप कर सकते हैं:

{{ blog_entry.comment_set.count }} 

टिप्पणियों की संख्या प्राप्त करने के लिए।

+0

हर बार जब मैं गिनती करता हूं() यह "टिप्पणी से चयन करें (1) कहां करेगा ..." जो बड़ी संख्या में टिप्पणियों के दौरान प्रदर्शन समस्याओं का कारण बन जाएगा। – slacy

+1

आपके ब्लॉग पर कितने लोग टिप्पणियां छोड़ रहे हैं? – mipadi

4

पहला दृष्टिकोण (संकेत) मॉडल के बीच युग्मन को खोने का लाभ है।
हालांकि, सिग्नल बनाए रखने के लिए किसी भी तरह से अधिक कठिन हैं, क्योंकि निर्भरता कम स्पष्ट (कम से कम, मेरी राय में) हैं।
यदि टिप्पणी गणना की शुद्धता इतनी महत्वपूर्ण नहीं है, तो आप क्रॉन नौकरी के बारे में भी सोच सकते हैं जो इसे हर n मिनट अपडेट करेगा।

हालांकि, समाधान से कोई फर्क नहीं पड़ता, denormalizing रखरखाव को और अधिक कठिन बना देगा; इस कारण से मैं को से जितना संभव हो सके, इसे कैश या अन्य तकनीकों का उपयोग करने के बजाय हल करने से बचने की कोशिश करता हूं - उदाहरण के लिए, टेम्पलेट्स में with comments.count as cnt का उपयोग करके प्रदर्शन में काफी सुधार हो सकता है।
फिर, यदि सब कुछ विफल हो जाता है, और केवल उस मामले में, इस बारे में सोचें कि विशिष्ट समस्या के लिए सबसे अच्छा तरीका क्या हो सकता है।

+0

मैं डेटा सामान्यीकरण (और denormalization) के इन-आउट-आउट को समझता हूं लेकिन ऐसे कई मामले हैं जहां denormalized डेटा क्वेरी प्रदर्शन में काफी वृद्धि कर सकता है, इसलिए मैं इसके बारे में सोच रहा हूं। मेरी "टिप्पणी गिनती" उदाहरण कृत्रिम है, लेकिन किसी भी denormalization प्रस्ताव के लिए एक अच्छा उदाहरण के रूप में कार्य करता है। कैशिंग एक अच्छा विचार है, और मैं इसे सोचना शुरू कर दूंगा ... – slacy

+0

कैशिंग में denormalization के सभी रखरखाव के मुद्दों, यानी कैश को अद्यतित रखना होगा, उचित होने पर कैश किए गए डेटा को अमान्य कर देना होगा। इससे भी बदतर आपको ऐसा करने के लिए Django ORM उपकरण का लाभ नहीं होगा। मेरा वोट django-denorm के लिए होगा @ gorsky ने सुझाव दिया है - यदि आपके पास कवर करने वाले मामलों में से एक है, तो यह आपके लिए सभी रखरखाव के मुद्दों का ख्याल रखता है। – Anentropic

9

मुझे उपयोगी होने के लिए django-denorm मिला। यह संकेतों के बजाय डेटाबेस-स्तरीय ट्रिगर्स का उपयोग करता है, लेकिन जहां तक ​​मुझे पता है, विभिन्न दृष्टिकोणों के आधार पर शाखा भी है।

+0

django-denorm के लिए +1 अपने स्वयं के संकेतों और ओवरराइड विधियों को मैन्युअल रूप से हैक करने के बजाय +1, यह एक महान और आसान प्रणाली है। – Anentropic

+0

मैंने django-denorm स्रोत कोड में देखा। मैं संचालन को हटाने के लिए हुक नहीं देखता ... क्या आप जानते हैं कि वे प्रबंधित हैं या नहीं? यह भी मुझे लगता है कि कोई डेटाबेस ट्रिगर्स का उपयोग नहीं किया जाता है, लेकिन यह बुरा नहीं है। मॉडल फ़ील्ड में पोस्ट-सेव विधियों द्वारा एक सामान्य तालिका अपडेट की जाती है। –

1

Django काउंटर denormalization के लिए एक महान और कुशल (हालांकि बहुत ज्ञात नहीं) विकल्प प्रदान करता है।

यह आपकी कई पंक्तियों को सहेज लेगा और यह वास्तव में धीमा है क्योंकि आप उसी SQL क्वेरी में गिनती पुनर्प्राप्त करते हैं। ,

class BlogEntry(models.Model): 
    title = models.CharField() 
    ... 


class Comment(models.Model): 
    body = models.TextField() 
    blog_entry = models.ForeignKey(BlogEntry) 

अपने views.py में annotations का उपयोग करें::

मैं तुम्हें इन कक्षाओं में है लगता होगा

from django.db.models import Count 

def blog_entry_list(Request): 
    blog_entries = BlogEntry.objects.annotate(count=Count('comment_set')).all() 
    ... 

और आप प्रत्येक ब्लॉग प्रविष्टि प्रति एक अतिरिक्त क्षेत्र, कि गणना शामिल होगा टिप्पणियों के साथ-साथ BlobEntry के बाकी क्षेत्रों।

आप टेम्पलेट्स भी में इस अतिरिक्त फ़ील्ड का उपयोग कर सकते हैं:

{% for blog_entry in blog_entries %} 
    {{ blog_entry.title }} has {{ blog_entry.count }} comments! 
{% endfor %} 

यह केवल आप कोडिंग और रखरखाव समय बचाने के लिए नहीं होगा लेकिन यह वास्तव में कुशल है (क्वेरी केवल थोड़ा अधिक समय निष्पादित करने के लिए लेता है)।

संबंधित मुद्दे