6

मेरे पास एक एएसपी.नेट एमवीसी वेबसाइट है। मेरी बैकएंड में मैं एक मेज निम्नलिखित कॉलम के साथ People कहा जाता है:डेटाबेस तालिका में उपयोगकर्ता फ़िल्टर किए गए क्वेरी पैरा को स्टोर करने का सबसे अच्छा तरीका क्या है?

  1. आईडी
  2. नाम
  3. उम्र
  4. स्थान
  5. ... (अन्य कॉलम के एक नंबर)

मेरे पास एक सामान्य वेब पेज है जो इस डेटा को क्वेरी करने के लिए मॉडल बाध्यकारी का उपयोग करता है।

public ActionResult GetData(FilterParams filterParams) 
{ 
     return View(_dataAccess.Retrieve(filterParams.Name, filterParams.Age, filterParams.location, . . .) 
} 

जो कुछ इस तरह पर नक्शे:

http://www.mysite.com/MyController/GetData?Name=Bill .. . 

dataAccess परत बस प्रत्येक पैरामीटर की जाँच करता है अगर इसकी आबादी वाले डाटाबेस जहां खंड में जोड़ने के लिए देखने के लिए यहाँ मेरी नियंत्रक कार्रवाई है। यह बहुत अच्छा काम करता है।

अब मैं उपयोगकर्ता के फ़िल्टर किए गए प्रश्नों को स्टोर करने में सक्षम होना चाहता हूं और मैं एक विशिष्ट फ़िल्टर को स्टोर करने का सबसे अच्छा तरीका जानने का प्रयास कर रहा हूं। चूंकि कुछ फ़िल्टरों में क्वेरीस्ट्रिंग में केवल एक पैरा है जबकि अन्य में फ़िल्टर में 10+ फ़ील्ड हैं, मैं अपने डेटाबेस में "फ़िल्टर जानकारी" इस क्वेरी को संग्रहीत करने का सबसे शानदार तरीका नहीं समझ सकता।

विकल्प मैं के बारे में सोच सकते हैं:

  1. (कुछ अतिरिक्त कॉलम के साथ) तालिका की एक पूरी दोहराने है लेकिन यह PeopleFilterQueries फोन और प्रत्येक रिकॉर्ड एक फ़िल्टर में देखने और में फिल्टर का मूल्य डाल प्रत्येक क्षेत्र (नाम, आदि)

  2. केवल फ़िल्टर नाम के साथ एक तालिका स्टोर करें और एक स्ट्रिंग जहां मैं वास्तविक क्वेरीस्ट्रिंग नाम = बिल & स्थान = न्यू यॉर्क। फिल्टर बदलने या बढ़ने पर इस तरह मुझे नए कॉलम जोड़ने की आवश्यकता नहीं होगी।

इस स्थिति के लिए सबसे अच्छा अभ्यास क्या है?

+0

फिल्टर * डेटा * का उद्देश्य क्या है? मैं * वास्तविक क्वेरी स्ट्रिंग को संग्रहीत करने की अनुशंसा नहीं करता हूं, लेकिन ** ** अगर और केवल अगर यह एक अपारदर्शी डेटा-प्रकार ** (मॉडल को wrt) है, तो मैं एक एन्कोडेड मान संग्रहीत करता हूं जो अच्छी तरह से किसी डोमेन ऑब्जेक्ट पर मैप करता है (और तुच्छ क्रमिकरण का समर्थन करता है)। यदि यह एक अपारदर्शी प्रकार है - या नहीं - आपकी आवश्यकताओं पर निर्भर करता है। –

+1

क्या आपको कभी भी इस डेटा से पूछने की आवश्यकता है? इसका उत्तर आपको क्रमबद्धता का उपयोग करने या फ़िल्टर क्वेरी तालिका + कुंजी/मान तालिका बनाने के लिए मार्गदर्शन करेगा। – dotjoe

+0

डेटाबेस में इसे संग्रहीत करने का कारण कौन सा है? रिपोर्टिंग के लिए है? रुझान? अंतिम फिल्टर याद रखना? यह फ़िल्टर जानकारी कितनी बार उपयोग की जाएगी? – ivowiblo

उत्तर

6

यदि उद्देश्य हाल ही में उपयोग किए गए फ़िल्टरों की एक सूची को सहेजना है, तो मॉडल बाध्यकारी होने के बाद मैं संपूर्ण फ़िल्टर पैराम ऑब्जेक्ट को XML फ़ील्ड/कॉलम में क्रमबद्ध कर दूंगा। इसे एक एक्सएमएल फ़ील्ड में सहेजकर आप XQuery और DML का उपयोग करने के लिए खुद को लचीलापन भी दे रहे हैं, जानकारी की अधिक प्रदर्शन केंद्रित क्वेरीिंग के लिए बाद की तारीख में आवश्यकता उत्पन्न होनी चाहिए।

public ActionResult GetData(FilterParams filterParams) 
    { 
      // Peform action to get the information from your data access layer here 
      var someData = _dataAccess.Retrieve(filterParams.Name, filterParams.Age, filterParams.location, . . .); 

      // Save the search that was used to retrieve later here 
      _dataAccess.SaveFilter(filterParams); 
      return View(someData); 
    } 

और फिर अपने DataAccess कक्षा में आप दो तरीके, को बचाने के लिए एक और फिल्टर पुन: प्राप्त करने के लिए एक से चर्चा करना चाहेंगे: जब आप किसी सहेजे गए फ़िल्टर प्राप्त करना चाहते हैं तो फिर

public void SaveFilter(FilterParams filterParams){ 
    var ser = new System.Xml.Serialization.XmlSerializer(typeof(FilterParams)); 
    using (var stream = new StringWriter()) 
      { 
       // serialise to the stream 
       ser.Serialize(stream, filterParams); 
      } 
    //Add new database entry here, with a serialised string created from the FilterParams obj 
    someDBClass.SaveFilterToDB(stream.ToString()); 
} 

, शायद ईद द्वारा:

public FilterParams GetFilter(int filterId){ 

     //Get the XML blob from your database as a string 
     string filter = someDBClass.GetFilterAsString(filterId); 

     var ser = new System.Xml.Serialization.XmlSerializer(typeof(FilterParams)); 

     using (var sr = new StringReader(filterParams)) 
     { 
      return (FilterParams)ser.Deserialize(sr); 
     } 
} 

याद रखें कि आपके FilterParams वर्ग एक डिफ़ॉल्ट (यानी parameterless) निर्माता, होना चाहिए और पी को रोकने के लिए [XmlIgnore] विशेषता का उपयोग कर सकते हैं रैपर्टीज को डेटाबेस में क्रमबद्ध करने से आपकी इच्छा होनी चाहिए।

public class FilterParams{ 
    public string Name {get;set;} 
    public string Age {get;set;} 

    [XmlIgnore] 
    public string PropertyYouDontWantToSerialise {get;set;} 
} 

नोट: सेवफिल्टर शून्य लौटाता है और ब्रेवटी के लिए कोई त्रुटि प्रबंधन नहीं है।

+0

यह वही है जो मैं उन वस्तुओं को सहेजने के लिए करता हूं जिन्हें कभी भी रिपोर्ट या पूछताछ की आवश्यकता नहीं होगी। यह विकल्प यह देखना मुश्किल होगा कि कितने उपयोगकर्ताओं के पास नाम = बॉब के साथ सहेजी गई क्वेरी है। और "मुश्किल" से मेरा मतलब है कि क्वेरी चलाने में काफी समय लगेगा। कोई अनुक्रमणिका नहीं, आदि –

+1

@DMoses अच्छी तरह से प्रदर्शन ओपी का सीधे हिस्सा नहीं था और मुझे नहीं लगता कि आप बस कुछ कह सकते हैं कि "क्वेरी चलाने के लिए बहुत समय" (और शायद डाउनवोट) इसे बैक अप किए बिना ले जाएगा कुछ मीट्रिक के साथ। 'एक्सप्ल्यू XmlField.value (' (// somePropertyName) [1] ',' PropertyType ') को चलाना [tableName]' के साथ एक तालिका पर एक XML फ़ील्ड के साथ 200k पंक्तियों में 13 प्रोप वाले XML पर एक्सएमएल से पार्स किया गया मान देता है 2 सेकंड से कम में - बिजली नहीं मैं सहमत हूं, लेकिन लचीलापन के लिए आपको वस्तुओं को बचाने के साथ मिलता है, मुझे लगता है कि भुगतान कुछ मामलों में इसके लायक है। – Tr1stan

+0

@tristan मैंने ऊपर उठाया और सोचा कि आपका जवाब अच्छा था। मैं चाहता था कि ओपी को एहसास हो कि एक प्रदर्शन ट्रेडऑफ था। –

2

क्वेरीस्ट्रिंग को संग्रहीत करने के बजाय, मैं FilterParams ऑब्जेक्ट को JSON/XML के रूप में क्रमबद्ध करता हूं और परिणाम को आपके डेटाबेस में संग्रहीत करता हूं।

यहाँ एक JSON Serializer है मैं नियमित रूप से उपयोग करें:

using System.IO; 
using System.Runtime.Serialization.Json; 
using System.Text; 

namespace Fabrik.Abstractions.Serialization 
{ 
    public class JsonSerializer : ISerializer<string> 
    { 
     public string Serialize<TObject>(TObject @object) { 
      var dc = new DataContractJsonSerializer(typeof(TObject)); 
      using (var ms = new MemoryStream()) 
      { 
       dc.WriteObject(ms, @object); 
       return Encoding.UTF8.GetString(ms.ToArray()); 
      } 
     } 

     public TObject Deserialize<TObject>(string serialized) { 
      var dc = new DataContractJsonSerializer(typeof(TObject)); 
      using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(serialized))) 
      { 
       return (TObject)dc.ReadObject(ms); 
      } 
     } 
    } 
} 

फिर आप वस्तु deserialize और यह ऊपर अपने उदाहरण के अनुसार अपने डेटा एक्सेस कोड पारित कर सकते हैं।

0

यह मानते हुए कि एक NoSQL/वस्तु डेटाबेस जैसे Berkeley DB सवाल से बाहर है, मैं निश्चित रूप से जल्द ही विकल्प 1. साथ जाना होगा या बाद में आप निम्न आवश्यकताओं को या दूसरों को आ रहा है मिल जाएगा:

  1. की अनुमति दें लोग अपने फ़िल्टर, लेबल, टैग, खोज को सहेजने और बुकमार्क्स, ट्वीट्स या जो भी हो, उन्हें साझा करते हैं।
  2. बदलें कि पैरामीटर का अर्थ क्या है या यह क्या करता है, जिसके लिए आपको पिछड़े संगतता के लिए अपने फ़िल्टर को संस्करणित करने की आवश्यकता होगी।
  3. स्वत: पूर्ण जानकारी को सूचित करने के लिए संभवतः उपयोगकर्ता के फ़िल्टर इतिहास का उपयोग करके फ़िल्टर पर स्वत: पूर्ण कार्य प्रदान करें।

उपर्युक्त कुछ भी बाइनरी/स्ट्रिंग क्रमबद्धता को संतुष्ट करने के लिए कुछ कठिन होगा, जहां आपको परिणाम का विश्लेषण करने और फिर उन्हें संसाधित करने की आवश्यकता होगी।

आप एक NoSQL डीबी का उपयोग कर सकते हैं, तो आप एक एसक्यूएल दुकान के सभी लाभ प्राप्त प्लस 'कुंजी/मान जोड़े के मनमाना संख्या' मॉडल के लिए बहुत अच्छी तरह से कर सकेंगे।

0

प्रोफाइल का उपयोग करने के बारे में सोचा है। यह उपयोगकर्ता विशिष्ट जानकारी को स्टोर करने के लिए तंत्र में एक निर्माण है। आपकी समस्या के आपके विवरण से यह एक उपयुक्त लगता है।

Profiles In ASP.NET 2.0

मुझे लगता है कि एम $ कार्यान्वयन थोड़ा दिनांकित है स्वीकार करना होगा लेकिन वहाँ अनिवार्य रूप से दृष्टिकोण के साथ कुछ भी गलत नहीं है। यदि आप अपना खुद का रोल करना चाहते हैं, तो उनके एपीआई में काफी अच्छी सोच है।

+1

एएसपी.नेट में प्रोफाइल बहुत बुनियादी उपयोगकर्ता प्रोफ़ाइल जानकारी के लिए उपयुक्त हैं, हालांकि डिफ़ॉल्ट कार्यान्वयन पर एक सरल क्वेरी करना मुश्किल है। इस पर एक नज़र डालें कि यह डेटाबेस में प्रोफाइल डेटा कैसे संग्रहीत करता है, http://weblogs.asp.net/andrewrea/archive/2008/03/04/how-asp-net-profile-properties-are-serialized-in- -डेटाबेस का उपयोग-एसक्यूएल प्रोफ़ाइल-provider.aspx –

2

आपने फ़िल्टर को संग्रहीत करने के सटीक उद्देश्य के बारे में उल्लेख नहीं किया है।

यदि आप डेटाबेस तालिका में फ़िल्टर को सहेजने का आग्रह करते हैं, तो मेरे पास तालिका की निम्न संरचना होगी।

  • FilterId
  • फील्ड
  • FieldValue

एक उदाहरण तालिका

FilterId Field FieldValue 
1  Name  Tom 
1  Age  24 
1  Location IL  
3  Name  Mike 
... 
2

जवाब और अधिक सरल है हो सकता है की तुलना में आप इसे बना रहे हैं:

आवश्यक तत्व कृपया आपको कच्ची क्वेरी को अपनी तालिका में स्टोर करना चाहिए और इसे अपनी पीपुल्स टेबल से जोड़ना चाहिए। अलग-अलग फ़िल्टर विकल्पों को संग्रहित करने से परेशान न हों।

स्टोर करने के लिए (2 विकल्प) एक मूल्य पर निर्णय लें

  1. स्टोर यूआरएल क्वेरी स्ट्रिंग

    इस आईडी फायदेमंद हो अगर आप खुला एपीआई शैली क्षुधा की तरह है, और चाहते हैं कुछ आप क्लाइंट से सर्वर पर अच्छी तरह से आगे और आगे पारित कर सकते हैं और परिवर्तन के बिना पुनः उपयोग कर सकते हैं।

  2. को क्रमानुसार एक स्ट्रिंग

    यह वास्तव में एक अच्छा दृष्टिकोण है, तो इन फिल्टर के भंडारण के लिए उद्देश्य पूरी तरह से सर्वर साइड रहता है, और आप डेटा एक वर्ग वस्तु के करीब रखने के लिए चाहते हैं के रूप में फ़िल्टर वस्तु।

अपने Query Filters Table करने के लिए अपने People तालिका संबंधित हैं:

सबसे अच्छा यहाँ रणनीति क्या आपका इरादा और प्रदर्शन जरूरतों को कर रहे हैं पर निर्भर करता है। नीचे कुछ सुझाव:

  • सरल फिल्टरिंग (। पूर्व 2-3 फिल्टर, 3-4 विकल्प प्रत्येक)

    उपयोग Many-To-Many संयोजनों की संख्या से पता चलता है, क्योंकि है कि एक ही फिल्टर कॉम्बो बहुत उपयोग किया जाएगा बहुत से लोगों द्वारा कई बार।

  • परिसर छानने

    उपयोग One-To-Many के रूप में वहाँ इतने सारे संभव व्यक्तिगत प्रश्न है, तो इसकी संभावना कम हो वे अक्सर अतिरिक्त सामान्य बनाने के लिए और प्रदर्शन अपने लायक मारा पर्याप्त पुन: उपयोग किया जा सकता है।

निश्चित रूप से अन्य विकल्प हैं लेकिन वे आपके आवेदन की अधिक विस्तृत व्याख्याओं पर निर्भर होंगे। यदि आप कहते हैं, उपरोक्त सुझाव उपयोगकर्ता के लिए "हालिया प्रश्न" या "उपयोगकर्ता पसंदीदा" फ़िल्टरिंग विकल्पों का ट्रैक रखने की कोशिश कर रहे हैं तो अच्छी तरह से काम करेंगे ...

व्यक्तिगत राय अपने अनुप्रयोग के बारे में अधिक जानने के बिना, मैं कहूंगा कि (1) स्टोर क्वेरी स्ट्रिंग, और (2) OTM संबंधित टेबल ... का उपयोग करते हैं और अपने ऐप के आगे प्रदर्शन के लिए एक की जरूरत को दर्शाता है प्रोफाइल पैराम को रिफैक्टरिंग के साथ प्रोफाइलिंग या समस्याएं, फिर वापस आएं ... लेकिन संभावना है, यह नहीं होगा।

जीएल।

1

मेरी राय में बचाने के लिए "फ़िल्टर" सबसे अच्छा तरीका है तो तुम

तरह DB में कुछ करना होगा "कॉलम नाम"

से प्रत्येक के साथ json पाठ स्ट्रिंग के कुछ प्रकार है करने के लिए है टेबल फ़िल्टर

फ़िल्टर आईडी = 5; FilterParams = { 'उम्र': '> 18', ...

Json ही "कॉलम" करने के लिए एक से अधिक फिल्टर करने के लिए एक सरणी, आदि के रूप में उम्र के उपयोग की तरह क्षमताओं का एक बहुत, प्रदान करेगा

इसके अलावा जेसन कुछ प्रकार का मानक है, इसलिए आप इस "फिल्टर" को किसी अन्य दिन डीबी के साथ या केवल "डिस्प्ले" फ़िल्टर या वेब फॉर्म में संपादित करने के लिए उपयोग कर सकते हैं। यदि आप क्वेरी को सहेजते हैं तो आप उससे जुड़े रहेंगे।

अच्छा, उम्मीद है कि यह मदद करता है!

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

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