2011-08-24 34 views
19

एक डेवलपर मुख्य रूप से सी # लिखने के रूप में मैंने सी # कोड लिखते समय कुछ अच्छे प्रथाओं को अपनाया है। जब मैं कभी-कभी संग्रहीत प्रक्रियाओं को लिखता हूं तो मुझे उन प्रथाओं को संग्रहीत प्रक्रिया कोड में लागू करने में परेशानी होती है।संग्रहित प्रक्रियाओं की संरचना का सर्वोत्तम अभ्यास

कई अवसरों पर मुझे दुःस्वप्न संग्रहीत प्रक्रिया कोड विरासत में मिला है, संग्रहीत प्रक्रियाओं की पहली तीन या चार परतें कुछ अस्थायी तालिकाओं को स्थापित करती हैं और ज्यादातर एक दूसरे को बुलाती हैं। कोई वास्तविक काम नहीं किया गया और कोड की कुछ पंक्तियां। फिर अंत में "अंतिम" संग्रहीत प्रक्रिया के लिए एक कॉल है, जो SQL कोड की 3000-5000 लाइनों का एक बड़ा राक्षस है। उस कोड में कोड कोड डुप्लिकेशंस, जटिल नियंत्रण प्रवाह (उर्फ स्पेगेटी) जैसी एक बहुत सी कोड गंध होती है और एक विधि जो एक दूसरे के बाद एक बहुत अलग चीज के साथ खड़ी होती है, जहां कोई काम शुरू नहीं होता है और यह कहां समाप्त होता है (यहां तक ​​कि एक भी नहीं एक विभाजक के रूप में टिप्पणी)।

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

स्पष्ट रूप से मेरे साथी टीम के साथी भी अच्छे एसक्यूएल लेखन प्रथाओं की कमी साझा करते हैं।

तो ... (और यहां वास्तविक सवाल आता है) ... मॉड्यूलर रखरखाव संग्रहित प्रक्रियाओं को लिखने के लिए अच्छे अभ्यास क्या हैं?

दोनों घरों के बने प्रथाओं और पुस्तकों/ब्लॉगों के संदर्भों का स्वागत है। विधियों के साथ-साथ उपकरण जो कुछ कार्यों के साथ मदद करते हैं।

कुछ क्षेत्रों में जहां मैं अच्छी प्रथाओं

नहीं मिला है संक्षेप में प्रस्तुत करने देता है
  • Modularization और कैप्सूलीकरण (संग्रहीत किया जाता है प्रक्रियाओं अस्थायी तालिकाओं वास्तव में जाने का रास्ता? के माध्यम से संचार)
    • सी # में मैं विधानसभाओं का उपयोग करें, कक्षाएं और इसे पूरा करने के लिए एक्सेस संशोधक के साथ सजाए गए तरीकों।
  • डिबगिंग/परीक्षण (डिबगिंग का लक्ष्य को संशोधित करने की तुलना में बेहतर?)
    • डीबग उपकरण?
    • डीबग निशान?
    • टेस्ट फिक्स्चर?
  • और कोड कोड
    • सी # में मैं refactor की संरचना का उपयोग सिर्फ एक तार्किक कार्य प्रत्येक करता है कि छोटे तरीकों को तोड़ने पर जोर देते कोड/तर्क/डेटा/नियंत्रण प्रवाह।
  • कोड दोहराव

ज्यादातर मैं डीबीएमएस के रूप में एसक्यूएल सर्वर मुठभेड़ लेकिन नास्तिक जवाब या उत्तर DBMS अन्य DBMS की सुविधाओं उनका कहना है: तों ऊपर मामलों में है कि मदद का भी स्वागत।

कुछ पृष्ठभूमि देने के लिए: सबसे बड़ी संग्रहीत प्रक्रियाओं का सामना करना पड़ रहा है परिदृश्य रिपोर्टिंग में जहां आधार एक बड़ी तालिका से कुछ सारांश मान बनाना है। लेकिन जिस तरह से आपको कुछ अपवाद तालिका में होने वाले कुछ मानों को बाहर करने की आवश्यकता है, कुछ अभी तक पूर्ण सामग्री तालिका में कुछ मान जोड़ें, पिछले वर्ष की तुलना करें (क्या आप कल्पना कर सकते हैं कि बदसूरत कोड जो उत्पाद बदलते विभाग को संभालता है वर्षों के बीच?), आदि

+2

इन कारणों के साथ-साथ एससीएम के साथ संग्रहीत प्रक्रियाओं का उपयोग करने में असमर्थता के कारण, मैंने उन सभी के लिए सबसे आवश्यक और स्पष्ट उपयोग (ट्रिगर, इत्यादि ...) से बचा है। हम व्यवसाय तर्क को व्यापार परत (.NET) में रखते हैं और केवल उस डेटा के लिए डेटाबेस का उपयोग करते हैं - डेटा बेस। – gahooa

+0

आदर्श रूप से, संग्रहीत प्रक्रियाओं को अन्य संग्रहीत प्रक्रियाओं को कॉल नहीं करना चाहिए। बीएल परत के लिए यही है। दुर्भाग्यवश, अगर आपके पास पहले से ही नेस्टेड एसपी कॉल से भरा डेटाबेस है तो वह भावना वास्तव में मदद नहीं करती है। क्या आप वर्तमान मॉडल को अधिक रखरखाव करने के तरीके, या सर्वोत्तम प्रणाली का बेहतर पालन करने के लिए अपने सिस्टम को दोबारा कैसे सुधारने के बारे में सलाह चाहते हैं, इस बारे में सलाह ले रहे हैं? –

+0

@ गहुआ मैंने जितना संभव हो सके .NET में भी (आंशिक रूप से क्योंकि यह मेरा घर क्षेत्र है) लेकिन कुछ मौकों पर, जैसे कि एक बड़े कोड बेस को विरासत में रखते हुए या जब आपके पास बड़ी मात्रा में डेटा होता है तो आप संग्रहित के साथ कम या ज्यादा अटक जाते हैं प्रक्रियाओं। –

उत्तर

13

मैं बहुत जटिल संग्रहित प्रोसेस लिखता हूं। कुछ चीजें जो मैं सर्वोत्तम प्रथाओं पर विचार करूंगा:

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

यदि आप एक proc (insert/update/delete) में एक से अधिक क्रिया क्वेरी कर रहे हैं, तो कैक्ट ब्लॉक और लेनदेन प्रसंस्करण का प्रयास करें। इनपुट पैरामीटर में एक टेस्ट पैरामीटर जोड़ें और जब यह 1 पर सेट किया गया है, तो हमेशा पूरे लेनदेन को रोलबैक करें। परीक्षण मोड में वापस रोल करने से पहले, मेरे पास आमतौर पर एक ऐसा अनुभाग होता है जो तालिकाओं में मान देता है जो मैं प्रभावित कर रहा हूं यह सुनिश्चित करने के लिए कि मुझे लगता है कि मैं डेटाबेस में क्या कर रहा हूं वास्तव में मैंने क्या किया है। या आप नीचे दिखाए गए चेक के रूप में जांच सकते हैं। एक बार आपके पास @test पैरामीटर होने के बाद आपके वर्तमान में टिप्पणी किए गए चारों ओर दिए गए कोड में निम्न कोड डालना उतना आसान है (और उन्हें असम्बद्ध करना)।

If @test =1 
Begin 
Select * from table1 where field1 = @myfirstparameter 
End 

अब आपको परीक्षण करने और हर बार परीक्षण करने की आवश्यकता नहीं है।

@test या @debuig हमेशा 0 के डिफ़ॉल्ट मान के साथ सेट किया जाना चाहिए और सूची में अंतिम रखा जाना चाहिए। इस तरह उन्हें जोड़ने से प्रो की मौजूदा कॉल नहीं टूट जाएंगी।

प्रविष्टियों/अपडेट/हटाए गए प्रोसेस के लिए लॉगिंग और/या त्रुटि लॉगिंग टेबल होने पर विचार करें। यदि आप टेबल वैरिएबल में चरणों और त्रुटियों को रिकॉर्ड करते समय रिकॉर्ड करते हैं, तो वे लॉगिंग तालिका में रोलबैक डालने के बाद भी उपलब्ध हैं। यह जानने के लिए कि एक जटिल proc का कौन सा हिस्सा असफल रहा और बाद में त्रुटि क्या अमूल्य हो सकती थी।

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

यदि आपके पास बहुत सी उप-सामान या व्युत्पन्न तालिकाओं के साथ जटिल चयन है, तो इसके बजाय सीटीई का उपयोग करने पर विचार करें। बेहतर निष्पादित सेट-आधारित कोड के लिए किसी भी सहसंबंधित सबक्वायरी या कर्सर को दोबारा दोहराएं। हमेशा डेटा के सेट के संदर्भ में एक रिकॉर्ड नहीं सोचते हैं।

किसी भी कल्पनीय परिस्थिति में, घोंसला विचारों के तहत नहीं। प्रदर्शन हिट बचाए गए विकास के समय की किसी भी छोटी राशि से भी बदतर है। और मुझ पर भरोसा करें, नेस्टेड विचार रखरखाव के समय को नहीं बचाते हैं जब परिवर्तन को दृश्यों की श्रृंखला में सबसे दूर देखने की आवश्यकता होती है।

सभी संग्रहीत प्रोसेस (और अन्य डेटाबेस कोड) स्रोत नियंत्रण में होना चाहिए।

तालिका चर छोटे डेटा सेट के लिए अच्छे हैं, लेकिन अस्थायी तालिकाओं (असली या जो # या ## स्टेजिंग टेबल के साथ शुरू होते हैं) बड़े डेटा सेट में प्रदर्शन के लिए बेहतर हो सकते हैं। यदि अस्थायी तालिकाओं का उपयोग करना उन्हें छोड़ देता है जब आपको अब उनकी आवश्यकता नहीं होती है। वैश्विक अस्थायी तालिकाओं के उपयोग से बचने की कोशिश करें।

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

+0

आरई नेस्टेड विचार: मैंने नेस्टेड विचारों वाला एक सिस्टम विरासत में लिया है, और SQL सर्वर पर प्रदर्शन जांच करने पर इसे कोई समस्या नहीं हुई है। हो सकता है कि यह एक मुद्दा हो, लेकिन एमएसएसएलएल 2008 में और क्वेरी प्लानर के ऊपर बहुत स्मार्ट और प्रभावशाली रूप से केवल दृश्य को रेखांकित करता है। –

+0

जिस सर्वर पर हमारे पास समस्या थी, वह एक SQL सर्वर 2008 सर्वर था। टी इस बात पर निर्भर हो सकता है कि tehw veiws कैसे लिखा जाता है। हमारी दूसरी समस्या यह थी कि विचारों को बनाए रखने के लिए हास्यास्पद रूप से कठिन हो गया और अंततः हम वास्तव में सिस्टम की हार्ड सीमा को प्रभावित करते थे और विचार बिल्कुल नहीं चल सके। मैंने जो कहा वह खड़ा है, अन्य विचारों को कॉल करने के लिए विचारों का उपयोग करना एक बुरा अभ्यास है। – HLGEM

5

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

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

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

मैं आपको सलाह देता हूं कि आप Ken Henderson's Guru's Guide to SQL Server Stored Procedures देखें - 2002 में प्रकाशित, यह अभी भी डेटाबेस एप्लिकेशन डिज़ाइन पर उपयोगी जानकारी का भरपूर धन है।

+0

शायद मैं गलतफहमी कर रहा हूं, लेकिन बिना किसी समस्या के कई उपयोगकर्ताओं के साथ अस्थायी तालिकाओं को चलाया जा सकता है। लेकिन शायद आप एक विशेष मामले के बारे में बात कर रहे हैं? –

+0

@ मार्क SQLDev आप सही हैं - स्थानीय अस्थायी तालिकाओं कनेक्शन-स्थानीय हैं - मुझे अस्थायी तालिकाओं (और तालिका चर) को डीबग करना मुश्किल लगता है। और, ज़ाहिर है, आप इस बारे में निर्णय ले रहे हैं कि क्या हासिल करना है और जब इसे ऑप्टिमाइज़र पर छोड़ने की बजाय। और आपको नामकरण का ट्रैक रखने की आवश्यकता है ताकि यह टकराव न हो। –

2

यह एक अच्छा सवाल है। एक सी # देव के रूप में मुझे एसक्यूएल में डबने लगते हैं, ऐसा लगता है कि एसक्यूएल अपनी प्रकृति से सर्वोत्तम प्रथाओं के रास्ते में आता है जिसका उपयोग मैं सी # के साथ करता हूं।

सामान्य तालिका एक्सपेशंस संग्रहीत प्रक्रिया में प्रश्नों को अलग करने के लिए बहुत अच्छे हैं लेकिन आप केवल एक बार उनका उपयोग कर सकते हैं! इससे आपको विचारों को परिभाषित किया जाता है लेकिन फिर आप अपना encapsulation खो दिया है।

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

इससे सब कुछ मुझे समय के साथ, डेटाबेस में सरल सीआरयूडी संग्रहीत प्रक्रियाओं (जो एक-दूसरे को कॉल नहीं करता) तक चिपकने के लिए प्रेरित करता है और कुछ अलग, प्रश्न होते हैं जब संबंध जटिल होते हैं। अधिक बीआई-सामान। बाकी सब कुछ बीएलएल में है।

शारीरिक रूप से, एसक्यूएल अलग-अलग फाइलों में अलग-अलग फाइलों में अलग होता है या तालिका जो वे घूमती है और स्रोत नियंत्रण में प्रबंधित होती है।

चयन * से बचें और कॉलम निर्दिष्ट करने का पक्ष लें। जब आप टेबल बदलते हैं और सभी प्रोसेस को स्पर्श नहीं करते हैं तो यह आपको रन-टाइम समस्याओं से बचाता है। हां, procs के लिए एक recompile है लेकिन यह कुछ याद आ जाएगा, खासकर अगर विचार शामिल हैं। इसके अलावा, चुनें * वास्तव में आपको हमेशा की आवश्यकता से अधिक कॉलम लौटाता है और यह बैंडविड्थ का अपशिष्ट है।

+0

निश्चित रूप से एसक्यूएल सर्वोत्तम प्रथाएं वही नहीं हैं जो आप सी # के साथ उपयोग की जाती हैं। संबंधपरक दुनिया में सी # सर्वोत्तम प्रथाओं का उपयोग करने की कोशिश करना बुरी तरह से प्रदर्शन करने वाले डेटाबेस के कारणों में से एक है। डेटाबेस को प्रदर्शन को अधिकतम करने के लिए डिज़ाइन किया गया है ताकि रखरखाव आसान न हो। – HLGEM

+0

और जब आप एक प्रो में एक से अधिक बार उपयोग करने की आवश्यकता होती है तो आप सीटीई के बजाय temp टेबल का उपयोग कर सकते हैं। – HLGEM

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