2010-12-11 7 views
6

मेरे पास काफी आम डिज़ाइन समस्या है: मुझे Google App Engine में रिकॉर्ड्स के लिए इतिहास लॉग (ऑडिट ट्रेल) लागू करने की आवश्यकता है। इतिहास लॉग को संरचित किया जाना चाहिए, यानी मैं स्ट्रिंग फ़ील्ड में कुछ फ्री-फॉर्म टेक्स्ट और स्टोर में सभी परिवर्तनों में शामिल नहीं हो सकता।Google App Engine में रिकॉर्ड परिवर्तनों के कुशल ऑडिट ट्रेल को कार्यान्वित करना - डिज़ाइन पैटर्न

मैंने इतिहास मॉडल के लिए निम्नलिखित विकल्प माना है और विकल्प # 1 में प्रदर्शन समस्याओं को ध्यान में रखते हुए, मैंने विकल्प # 3 को लागू करना चुना है। लेकिन अगर यह समाधान कुशल और स्केलेबल है तो कुछ संदेह बढ़ाएं। उदाहरण के लिए: क्या कोई जोखिम है कि विकल्प # 3 में गतिशील गुणों की संख्या में उल्लेखनीय रूप से गिरावट आएगी?

क्या आपके पास प्रत्येक विकल्प के लिए पेशेवरों/विपक्ष पर कुछ गहरा ज्ञान है या Google App Engine DB विशेषताओं के लिए लागू अन्य ऑडिट ट्रेल डिज़ाइन पैटर्न का सुझाव दे सकता है?

  1. उपयोग क्लासिक एसक्यूएल "गुरु-विस्तार" संबंध
    • पेशेवरों
      • एसक्यूएल पृष्ठभूमि
      • स्वच्छ साथ डाटाबेस डेवलपर्स के लिए समझने के लिए सरल: इतिहास रिकार्ड के लिए प्रत्यक्ष परिभाषा और उसके गुणों
      • खोज प्रदर्शन: इतिहास के माध्यम से आसान खोज (सूचकांक का उपयोग कर सकते हैं)
      • समस्या निवारण: प्रशासनिक उपकरण (_ah/admin)द्वारा आसान पहुंच
    • विपक्ष
      • एक-से-कई संबंध अक्सर GAE डीबी में इस तरह से लागू किया जा करने के लिए सिफारिश नहीं कर रहे हैं
      • पढ़ने प्रदर्शन: रिकॉर्ड की अत्यधिक संख्या जैसे लंबे लेखापरीक्षा निशान दिखाने के लिए आपरेशन पढ़ा एक बड़ी रिकॉर्ड सूची के विवरण फलक में। ब्लॉब क्षेत्र में
  2. स्टोर इतिहास (मसालेदार अजगर संरचनाओं)
    • पेशेवरों
      • लागू करने के लिए सरल और लचीला
      • पढ़ने प्रदर्शन: बहुत ही कुशल
    • विपक्ष
        ,210 क्वेरी प्रदर्शन: सूचकांकों का उपयोग कर खोज नहीं कर सकते
      • समस्या निवारण: व्यवस्थापक db दर्शक (_ah/व्यवस्थापक) द्वारा डेटा का निरीक्षण नहीं कर सकते
      • अशुद्ध: तो समझ में/एसक्यूएल डेवलपर्स के लिए स्वीकार करते हैं (वे इस बदसूरत पर विचार करें)
    • करने के लिए आसान नहीं
  3. एक्सपोन्डो की गतिशील गुणों में स्टोर इतिहास। जैसे प्रत्येक फ़ील्ड के लिए fieldNamehistory_fieldName_n फ़ील्ड बनाएं (जहां n = < 0 ..
    • सरल: सरल को लागू करने और समझने के
    • समस्या निवारण करने के लिए: एक पढ़ा आपरेशन करने के लिए: व्यवस्थापक इंटरफ़ेस
    • पढ़ने प्रदर्शन के माध्यम से सभी इतिहास गुण पढ़ सकते हैं एन> इतिहास रिकॉर्ड की एक संख्या)
      • पेशेवरों है
        • खोज प्रदर्शन: बस इतिहास रिकॉर्ड के माध्यम से खोज नहीं कर सकते हैं (वे हवलदार रिकॉर्ड
      • विपक्ष मिल ई अलग नाम)
      • नहीं
      • भी साफ: प्रॉपर्टी की संख्या पहले देखो पर
  4. स्टोर इतिहास मुख्य रिकॉर्ड में सूची में से कुछ फ़ील्ड सेट में भ्रमित हो सकता है। उदाहरण के लिए।
  5. पढ़ने प्रदर्शन एसक्यूएल डेवलपर्स के लिए समझने में आसान:
    • साफ: इतिहास गुणों का सीधा परिभाषा
    • सरल प्रत्येक fieldName के लिए एक fieldName_history सूची क्षेत्र
      • पेशेवरों बनाने एक पढ़ा आपरेशन रिकॉर्ड प्राप्त करने के लिए
    • विपक्ष:
      • खोज प्रदर्शन: सूचकांकों का उपयोग कर खोज कर सकते हैं ओ उन अभिलेखों के लिए जो कभी भी कुछ मूल्य रखते थे और कुछ विशेष समय पर मूल्यों के संयोजन वाले रिकॉर्ड की खोज नहीं कर सकते;
      • समस्या निवारण: निरीक्षण सूचियों व्यवस्थापक db दर्शक में मुश्किल है

उत्तर

3

मुझे लगता है मैं विकल्प 1. पढ़ता के लिए जाना होगा चयन करना चाहते हैं के लिए performant के रूप में (न अधिक हो) कर रहे हैं अन्य विकल्प। और अन्य सभी विकल्पों में केवल विशिष्ट परिस्थितियों (परिवर्तनों के छोटे या बहुत बड़े सेट) के तहत गति लाभ होते हैं। यह आपको कई प्रकार के लचीलेपन (अधिक आसानी से) प्राप्त करेगा जैसे x दिनों के बाद इतिहास को शुद्ध करना या विभिन्न मॉडल प्रकारों में क्वेरी इतिहास। सुनिश्चित करें कि आप स्थिरता की गारंटी के लिए एक ही लेनदेन में बदली हुई इकाई के बच्चे के रूप में इतिहास संस्थाएं बनाते हैं। आप इनमें से किसी एक के साथ समाप्त हो सकते हैं:

class HistoryEventFieldLevel(db.Model): 
    # parent, you don't have to define this 
    date = db.DateTime() 
    model = db.StringProperty() 
    property = db.StringProperty() # Name of changed property 
    action = db.EnumProperty(['insert', 'update', 'delete']) 
    old = db.PickleProperty() # Old value for field, empty on insert 
    new = db.PickleProperty() # New value for field, empty on delete 

class HistoryEventModelLevel(db.Model): 
    # parent, you don't have to define this 
    date = db.DateTime() 
    model = db.StringProperty() 
    action = db.EnumProperty(['insert', 'update', 'delete']) 
    change = db.PickleProperty() # Dictionary with changed fields as keys and tuples (old value, new value) as values