नेस्टेड एंटिटीज और लीफ यूनिट प्रॉपर्टी पर कैलकुलेशन - SQL या NoSQL अप्रोच


10

मैं एक शौक परियोजना पर काम कर रहा हूं जिसे मेनू / पकाने की विधि प्रबंधन कहा जाता है।

इसी तरह से मेरी संस्थाएं और उनके संबंध दिखते हैं।

A Nutrientमें गुण हैं CodeऔरValue

एक Ingredientका संग्रह हैNutrients

A के Recipeपास संग्रह है Ingredientsऔर कभी-कभी अन्य का संग्रह हो सकता हैrecipes

A Mealका एक संग्रह है RecipesऔरIngredients

A Menuका एक संग्रह हैMeals

संबंधों का चित्रण किया जा सकता है

मेनू संस्थाओं और रिश्ते

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

अब तक डेटा को स्टोर करने के लिए एसक्यूएल सर्वर का उपयोग कर रहा हूं और मैं अपने सी # कोड से चेन को नेविगेट कर रहा हूं, मेनू के प्रत्येक भोजन से शुरू कर रहा हूं और फिर पोषक मूल्यों को एकत्र कर रहा हूं।

मुझे लगता है कि यह एक कुशल तरीका नहीं है क्योंकि यह गणना हर बार पृष्ठ का अनुरोध करने के बाद की जा रही है और घटक कभी-कभी बदलते हैं।

मैं एक पृष्ठभूमि सेवा होने के बारे में सोच रहा था जो MenuNutrients ( {MenuId, NutrientId, Value}) नामक एक तालिका बनाए रखता है और किसी भी घटक (भोजन, पकाने की विधि, घटक) में परिवर्तन होने पर प्रभावी पोषक तत्वों के साथ इस तालिका को आबाद / अपडेट करेगा।

मुझे लगता है कि इस आवश्यकता के लिए एक ग्राफडीबी एक अच्छा फिट होगा, लेकिन NoSQL के लिए मेरा जोखिम सीमित है।

मैं जानना चाहता हूं कि दिए गए मेनू के पोषक तत्वों को प्रदर्शित करने की इस आवश्यकता के वैकल्पिक समाधान / दृष्टिकोण क्या हैं।

आशा है कि परिदृश्य का मेरा विवरण स्पष्ट है।


हम कितनी वस्तुओं की बात कर रहे हैं? क्या वास्तव में प्रदर्शन एक मुद्दा होगा?
23

@flup औसतन एक मेनू में 8 भोजन हो सकते हैं, प्रत्येक भोजन में 2 व्यंजन और 2 सामग्री हो सकती हैं, प्रत्येक नुस्खा में 6-8 सामग्री हो सकती हैं।
चंदू

क्या आपके तीर गलत दिशा में नहीं हैं?
ब्रैंको दिमित्रिजेविक

क्या आपने Nerd Dinner Entity Framework नमूना देखा है?
आकाश काव

जवाबों:


8

आवश्यकताओं और वास्तुकला के आधार पर, प्रदर्शन में सुधार के विकल्प हो सकते हैं:

  • आरडीबीएमएस (एसक्यूएल सर्वर) स्तर पर रीड परफॉर्मेंस को बेहतर बनाने के लिए आप अनुक्रमित दृश्यों (मैट्रीलाइज्ड) का उपयोग कर सकते हैं । मूल रूप से, आपको बस इतना करना है: एक नियमित दृश्य बनाएं। उस दृश्य पर एक संकुल सूचकांक बनाएँ



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

NoSql:
Sql बनाम NoSql के बारे में बहुत सारे अच्छे लेख हैं, जैसे यह और यह

हिस्से मुझे

रुचिकर बनाते हैं: NoSql का उपयोग कहां करें:

यदि आपका DB 3NF है और आप कोई जॉइन नहीं करते हैं (आप सिर्फ टेबल का एक गुच्छा चुन रहे हैं और सभी ऑब्जेक्ट्स को एक साथ रख रहे हैं, तो AKA एक वेब ऐप में ज्यादातर लोग क्या करते हैं।

जब उपयोग के लिए तैयार हों:

  • आप अलग-अलग टेबल / कलेक्शन के डेटा से जुड़ने जैसे काम करने के लिए जॉब राइटिंग करते हैं, कुछ ऐसा जो RDBMS आपके लिए अपने आप करेगा।
  • NoSQL के साथ आपकी क्वेरी क्षमताएं बेहद अपंग हैं। MongoDb SQL की सबसे करीबी चीज हो सकती है लेकिन यह अभी भी बहुत पीछे है। मुझ पर विश्वास करो। SQL क्वेरी सुपर सहज, लचीली और शक्तिशाली हैं। NoSql क्वेरी नहीं हैं।
  • MongoDb क्वेरी केवल एक संग्रह से डेटा पुनर्प्राप्त कर सकती है और केवल एक इंडेक्स का लाभ उठा सकती है। और MongoDb शायद सबसे लचीली NoSQL डेटाबेस में से एक है। कई परिदृश्यों में, इसका अर्थ संबंधित रिकॉर्ड खोजने के लिए सर्वर पर अधिक गोल-यात्राएं हैं। और फिर आप डेटा को सामान्य करना शुरू करते हैं - जिसका अर्थ है पृष्ठभूमि की नौकरियां।
  • तथ्य यह है कि यह एक संबंधपरक डेटाबेस नहीं है, इसका मतलब है कि आपके पास यह सुनिश्चित करने के लिए विदेशी कुंजी की कमी है कि आपके डेटा के अनुरूप होने के लिए (कुछ लोगों द्वारा बुरा प्रदर्शन करने के लिए सोचा) नहीं होगा। मैं आपको विश्वास दिलाता हूं कि यह अंततः आपके डेटाबेस में डेटा विसंगतियां पैदा करने वाला है। तैयार रहो। सबसे अधिक संभावना है कि आप अपने डेटाबेस को सुसंगत रखने के लिए प्रक्रियाएं या जांच लिखना शुरू कर देंगे, जो शायद आरडीबीएमएस को आपके लिए ऐसा करने से बेहतर प्रदर्शन नहीं करेगा।
  • हाइबरनेट जैसे परिपक्व ढांचे के बारे में भूल जाओ।

NoSql का उपयोग करने या न करने का निर्णय लेने के अलावा, NOSQL DBMS तुलना पर एक उपयोगी लेख और उनमें से कुछ के रूप में यहाँ पाया जा सकता है उनमें से कुछ उच्च रीड, कम लिखता है, नक्शे को कम करने, हा ... पर
एक नज़र श्रेणी के आधार पर, उनकी रैंकिंग और लोकप्रियता उपयोगी हो सकती है।


विवरण के लिए धन्यवाद। लिंक की जाँच करेगा और आपके पास वापस आएगा।
चंदू

3

मुझे लगता है कि आपको एक ग्राफ डीबी का उपयोग करने की आवश्यकता नहीं है, बस एक ऊपरी स्तर में आवश्यक मूल्यों को संग्रहीत करें। यह सिर्फ एक भंडारण की तरह है Orderऔर OrderItems। जब भी कोई आदेश प्रदर्शित होने वाला हो, तो आपको कुल गणना करने की आवश्यकता नहीं है। इसके बजाय आप बस राशि, वैट और अन्य सामान की गणना करें और उन्हें अपने साथ स्टोर करें Order

order.Subtotal = order.Items.Sum(item => item.Price);
order.Tax = order.Subtotal * 0.25m; // just a value
order.Total = order.Subtotal + order.Tax;

// fast forward time
var subTotal = order.Items.Sum(item => item.Price);
var tax = subTotal * 0.25m;
var total = subTotal + tax;

if (toal == order.Total) {
   Console.Log("Why the hell I've just re-calculated total?");
}

3

मैं कमांड क्वेरी रिस्पॉन्सिबिलिटी सेग्रीगेशन पैटर्न को देखने का सुझाव देता हूं ।

मूल रूप से पढ़ने और लिखने के लिए एक एकल मॉडल बनाने के बजाय आप 2 अलग-अलग मॉडल बना सकते हैं। एक अद्यतन करने के लिए अनुकूलित और दूसरा प्रश्नों के लिए अनुकूलित (पढ़ें, रिपोर्टिंग, ...)। डोमेन इवेंट (DDD देखें) का उपयोग करके 2 मॉडल सिंक्रनाइज़ किए जाते हैं (आमतौर पर अंतिम स्थिरता के साथ)।

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

नेट पर कई संसाधन उपलब्ध हैं, CQRS और DDD (और अंततः इवेंट सोर्सिंग) की खोज करें।

इस पैटर्न का उपयोग SQL और noSql दोनों पर किया जा सकता है।

आपके मामले में आप किसी घटना को पढ़ सकते हैं जिसे पढ़ने के लिए ऑप्टिमाइज़ किए गए रीड मॉडल को अपडेट करने के लिए पोषक तत्वों को बदल दिया जाता है। उदाहरण के लिए पढ़ा गया मॉडल मेनू के पोषक तत्वों का एक असामान्य दृष्टिकोण हो सकता है (कुशल पढ़ने के लिए नोस्कल डीबी का उपयोग क्यों नहीं किया जाए)। आपके द्वारा निष्पादित किए जाने वाले प्रश्नों के आधार पर आपके पास कई रीड मॉडल हो सकते हैं।

इस दृष्टिकोण का उपयोग करने के कुछ निहितार्थ हैं लेकिन यह बहुत ही स्केलेबल और एक्स्टेंसिबल है।


यह वह दृष्टिकोण था जिस पर मैं विचार कर रहा था, लेकिन यह सुनिश्चित नहीं था कि रीड मॉडल के लिए डेटा कैसे प्राप्त किया जाए (मूल रूप से कुछ प्रक्रिया मुझे रीड मॉडल के लिए डेटा प्राप्त करना चाहिए)।
चंदू

आमतौर पर प्रत्येक परिवर्तन पर रीड मॉडल अपडेट किया जाता है। आपको क्रूड संचालन का उपयोग करने के बजाय आदेशों (कार्य आधारित) के साथ यूआई को लागू करना चाहिए। इस तरह से हर एक कमांड रीड मॉडल परिलक्षित होता है। आपको अन्य प्रश्नों को निष्पादित करने की आवश्यकता नहीं है। डिजाइनिंग कमांड सिस्टम को उपयोगकर्ता के वास्तविक इरादे को पकड़ने की अनुमति देता है।

2

यह बहुत कुछ इस बात पर निर्भर करता है कि आप शुरू में मेनू और पोषक तत्व कैसे प्राप्त करते हैं। आपको क्यों लगता है कि यह कुशल नहीं होगा?

जो मैं समझता हूं, आप डीबी पर जाते हैं, मेनू प्राप्त करते हैं, फिर फिर से जाते हैं, प्रत्येक नुस्खा प्राप्त करते हैं, फिर से जाते हैं और प्रत्येक घटक और इसी तरह प्राप्त करते हैं। यह वास्तव में अक्षम है, क्योंकि सर्वर पर बहुत सारी क्वेरी और राउंड-ट्रिप हैं, जो देरी का मुख्य स्रोत है। इसे SELECT N + 1 समस्या के रूप में जाना जाता है।

JOINपोषक तत्वों तक के मेनू से सभी तालिकाओं के लिए s का उपयोग करके, आपको एक ही क्वेरी में सभी डेटा प्राप्त करने के लिए क्या करना चाहिए , इसलिए DB सर्वर सभी डेटा को एक साथ प्राप्त करने के लिए सभी रिश्तों और अनुक्रमित का उपयोग कर सकता है। क्लाइंट C # ऐप केवल प्रक्रिया करता है और अंतिम परिणाम प्रदर्शित करता है। ऐसा करना एक के बाद एक जाने से कहीं अधिक कुशल है।

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


धन्यवाद, मैं समझता हूं कि यह जुड़ावों पर निर्भर करता है। चूंकि मेनू के घटक कभी-कभी बदलते हैं, इसलिए मैं गणना को हर बार चलाना नहीं चाहता, क्योंकि कोई पृष्ठ को हिट करता है। इसके बजाय मुझे गणना करने के लिए एक पृष्ठभूमि सेवा चाहिए और मैं बस जरूरत पड़ने पर इसे एक तालिका से पढ़ सकता हूं। गणना के साथ मुद्दा पूरी श्रृंखला की पहचान कर रहा है जब एक घटक बदलता है।
चंदू

बस कुछ संबंधों की खोज किसी भी गणना में नहीं होती है, भले ही 5 या 6 JOINs हैं जो सर्वर पर बोझ नहीं होना चाहिए (जब तक कि हम सैकड़ों या हजारों पंक्तियों को लाने की बात नहीं कर रहे हैं), यदि उचित अनुक्रमण जगह पर है। यहां तक ​​कि बड़े डेटा सेट के साथ, आप हमेशा पूरे परिणाम पर एक दृश्य का निर्माण कर सकते हैं, और यहां तक ​​कि परिणाम को पूर्व निर्धारित करने के लिए दृश्य को अनुक्रमित करते हैं, अगर प्रदर्शन कभी भी समस्या बन जाता है।

2

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

आप उल्लेख करते हैं कि पृष्ठ को फिर से लोड करने से डेटाबेस में एक नई क्वेरी पैदा हो रही है। आप यह भी उल्लेख करते हैं कि डेटाबेस कभी-कभार अपडेट किया जाएगा और जब आप चाहें तो उन अपडेट को समय पर पृष्ठ पर प्रदर्शित किया जाएगा। प्रश्नों के ओवरहेड को कम करने का आपका सबसे अच्छा तरीका उन्हें नहीं करना है। यदि आप एक ही क्वेरी को बार-बार चला रहे हैं और एक ही परिणाम प्राप्त कर रहे हैं, तो उन्हें थोड़ी देर के लिए कैश क्यों न करें? आपको परियोजना के बाकी हिस्सों को संशोधित किए बिना कुछ कैशिंग अपस्ट्रीम को लागू करने में सक्षम होना चाहिए। मैं आराम करने के बारे में पढ़ने की सलाह दूंगा। भले ही यदि आप प्रोजेक्ट को rdbms में लागू करते हैं या इस प्रकार के प्रदर्शन के साथ nosql समस्याएँ हैं, तो आपको डेटाबेस में जाने के समय की संख्या को कम करके सबसे अच्छा नियंत्रित किया जाता है। मान लें कि आपके पास एक ही नुस्खा के लिए 60 सेकंड में 100 अनुरोध हैं। यदि आप 60 सेकंड के लिए कैश करते हैं तो आप केवल डेटाबेस को एक बार हिट करते हैं ताकि प्रदर्शन में 100 गुना सुधार हो। देखने के लिए कि nosql पर स्विच करके सुधार के समान स्तर को बहुत अधिक काम की आवश्यकता है।

जब आपके पास भारी मात्रा में डेटा या चरम पढ़ने या लिखने की गति की आवश्यकता हो तो नोस्कल टाइप सिस्टम एक बेहतरीन समाधान हो सकता है। हालाँकि यह अतिरिक्त प्रदर्शन संदर्भात्मक अखंडता जैसी चीजों को फेंकने की लागत पर आता है।


1

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


1

मेरा सुझाव मशीन की तरह सोचना है न कि इंसान की तरह। यह दोहराव लग सकता है, लेकिन यह है कि क्या मशीनों में अच्छे हैं। एक बात जो आपको खुद से पूछनी है वह यह है कि "क्या मुझे हर वस्तु को पुनः प्राप्त करना है, वैसे भी, अपने पृष्ठ पर प्रदर्शित करने के लिए?" यदि हाँ, तो जारी रखें कि आप क्या कर रहे हैं, डेटा पुनर्प्राप्ति की तुलना में, सरल गणित करते समय सीपीयू चक्र नगण्य हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.