नामित तालिका अभिव्यक्तियों के बारे में श्रृंखला में यह 9वां भाग है। भाग 1 में मैंने नामित तालिका अभिव्यक्तियों को पृष्ठभूमि प्रदान की, जिसमें व्युत्पन्न तालिकाएं, सामान्य तालिका अभिव्यक्ति (सीटीई), विचार और इनलाइन तालिका मूल्यवान फ़ंक्शन (आईटीवीएफ) शामिल हैं। भाग 2, भाग 3 और भाग 4 में मैंने व्युत्पन्न तालिकाओं पर ध्यान केंद्रित किया। भाग 5, भाग 6, भाग 7 और भाग 8 में मैंने सीटीई पर ध्यान केंद्रित किया। जैसा कि मैंने समझाया, व्युत्पन्न टेबल और सीटीई स्टेटमेंट-स्कोप नामित टेबल एक्सप्रेशन हैं। एक बार जब उन्हें परिभाषित करने वाला कथन समाप्त हो जाता है, तो वे समाप्त हो जाते हैं।
अब हम पुन:प्रयोज्य नामित तालिका अभिव्यक्तियों के कवरेज के लिए आगे बढ़ने के लिए तैयार हैं। यही है, जो डेटाबेस में ऑब्जेक्ट के रूप में बनाए जाते हैं, और जब तक गिराए नहीं जाते तब तक वहां स्थायी रूप से बने रहते हैं। जैसे, वे उन सभी के लिए सुलभ और पुन:प्रयोज्य हैं जिनके पास सही अनुमति है। दृश्य और iTVF इस श्रेणी में आते हैं। दोनों के बीच मुख्य रूप से यह अंतर है कि पहला इनपुट पैरामीटर का समर्थन नहीं करता है और बाद वाला करता है।
इस लेख में मैं विचारों का कवरेज शुरू करता हूं। जैसा कि मैंने पहले किया था, मैं पहले तार्किक, या वैचारिक, पहलुओं पर ध्यान केंद्रित करूंगा, और बाद में अनुकूलन पहलुओं पर आगे बढ़ूंगा। विचारों पर पहले लेख के साथ, मैं सही शब्दावली का उपयोग करते हुए, एक दृश्य पर ध्यान केंद्रित करते हुए, प्रकाश शुरू करना चाहता हूं, और पहले चर्चा की गई व्युत्पन्न तालिकाओं और सीटीई के विचारों के डिजाइन विचारों की तुलना करना चाहता हूं।
अपने उदाहरणों में मैं TSQLV5 नामक एक नमूना डेटाबेस का उपयोग करूँगा। आप इसे बनाने और भरने वाली स्क्रिप्ट यहां और इसके ईआर आरेख यहां देख सकते हैं।
दृश्य क्या है?
संबंधपरक सिद्धांत पर चर्चा करते समय हमेशा की तरह, हम SQL चिकित्सकों को अक्सर बताया जाता है कि हम जिस शब्दावली का उपयोग कर रहे हैं वह गलत है। तो, इस भावना में, सीधे बल्ले से, मैं यह कहकर शुरू करूँगा कि जब आप टेबल और दृश्य शब्द का उपयोग करते हैं , यह गलत है। मैंने इसे क्रिस डेट से सीखा है।
याद रखें कि एक तालिका एक संबंध के लिए SQL का समकक्ष है (मूल्यों और चर के आसपास की चर्चा को थोड़ा अधिक सरल बनाना)। एक तालिका डेटाबेस में एक वस्तु के रूप में परिभाषित एक आधार तालिका हो सकती है, या यह एक अभिव्यक्ति द्वारा दी गई तालिका हो सकती है - विशेष रूप से, एक तालिका अभिव्यक्ति। यह इस तथ्य के समान है कि एक संबंध वह हो सकता है जो एक संबंधपरक अभिव्यक्ति से लौटा हो। एक टेबल एक्सप्रेशन एक क्वेरी हो सकती है।
अब, दृश्य क्या है? यह एक नामित तालिका अभिव्यक्ति है, सीटीई की तरह एक नामित तालिका अभिव्यक्ति है। यह वैसा ही है जैसा मैंने कहा, एक दृश्य एक पुन:प्रयोज्य नामित तालिका अभिव्यक्ति है जो डेटाबेस में एक वस्तु के रूप में बनाई गई है, और उन लोगों के लिए सुलभ है जिनके पास सही अनुमति है। यह सब कहना है, एक दृश्य एक मेज है। यह आधार तालिका नहीं है, बल्कि फिर भी एक तालिका है। तो जैसे "एक आयत और एक वर्ग" या "एक व्हिस्की और एक लैगावुलिन" कहना अजीब लगेगा (जब तक कि आपके पास बहुत अधिक लैगावुलिन न हो!), "तालिकाओं और विचारों" का उपयोग करना उतना ही अनुचित है।
सिंटैक्स
क्रिएट व्यू स्टेटमेंट के लिए टी-एसक्यूएल सिंटैक्स यहां दिया गया है:
बनाएँ [या बदलें] देखें [<स्कीमा नाम>। ] <तालिका का नाम> [ (<लक्ष्य स्तंभ>) ][ SCHEMABINDING सहित <दृश्य विशेषताओं के साथ> ]
AS
<तालिका अभिव्यक्ति>
[ जांच विकल्प के साथ ]
[; ]
क्रिएट व्यू स्टेटमेंट बैच में पहला और एकमात्र स्टेटमेंट होना चाहिए।
ध्यान दें कि SQL सर्वर 2016 SP1 में CREATE OR ALTER भाग पेश किया गया था, इसलिए यदि आप पुराने संस्करण का उपयोग कर रहे हैं, तो आपको अलग-अलग CREATE VIEW और ALTER VIEW स्टेटमेंट के साथ काम करना होगा, जो इस बात पर निर्भर करता है कि ऑब्जेक्ट पहले से मौजूद है या नहीं। जैसा कि आप शायद अच्छी तरह से जानते हैं, मौजूदा ऑब्जेक्ट को बदलने से असाइन की गई अनुमतियां बरकरार रहती हैं। यही एक कारण है कि आमतौर पर किसी मौजूदा वस्तु को गिराने और फिर से बनाने के बजाय उसे बदलना समझदारी है। कुछ लोगों को आश्चर्य होता है कि किसी दृश्य को बदलने से मौजूदा दृश्य विशेषताओं को बरकरार नहीं रखा जाता है; यदि आप उन्हें बनाए रखना चाहते हैं तो उन्हें निर्दिष्ट करने की आवश्यकता है।
यूएसए ग्राहकों का प्रतिनिधित्व करने वाली एक साधारण दृश्य परिभाषा के लिए यहां एक उदाहरण दिया गया है:
TSQLV5 का उपयोग करें; क्रिएट करें या बिक्री देखें।USACustomersAS सेलेक्ट कस्टिड, कंपनी का नाम सेल्स से। ग्राहक जहां देश =N'USA';GO
और यहां एक बयान दिया गया है जो दृश्य पर सवाल उठाता है:
कस्टिड चुनें, कंपनी का नाम Sales.USAग्राहकों से;
उस कथन के बीच जो दृश्य बनाता है, और वह कथन जो उससे पूछताछ करता है, आपको वही तीन तत्व मिलेंगे जो किसी व्युत्पन्न तालिका या CTE के विरुद्ध कथन में शामिल हैं:
- आंतरिक तालिका अभिव्यक्ति (दृश्य की आंतरिक क्वेरी)
- असाइन की गई तालिका का नाम (दृश्य नाम)
- दृश्य के विरुद्ध बाहरी क्वेरी वाला कथन
आपमें से जिन लोगों ने गहरी निगाह रखी होगी, उन्होंने देखा होगा कि वास्तव में यहां दो टेबल एक्सप्रेशन शामिल हैं। एक आंतरिक (दृश्य की आंतरिक क्वेरी) है, और एक बाहरी है (दृश्य के विरुद्ध कथन में क्वेरी)। कथन में दृश्य के विरुद्ध क्वेरी के साथ, क्वेरी स्वयं एक तालिका अभिव्यक्ति है, और एक बार जब आप टर्मिनेटर जोड़ते हैं, तो यह एक कथन बन जाता है। यह अटपटा लग सकता है, लेकिन यदि आप इसे प्राप्त करते हैं, और चीजों को उनके सही नाम से पुकारते हैं, तो यह आपके ज्ञान को दर्शाता है। और क्या यह बहुत अच्छा नहीं है जब आप जानते हैं कि आप जानते हैं?
साथ ही, व्युत्पन्न तालिकाओं और CTE में तालिका व्यंजक की सभी आवश्यकताएं, जिनकी चर्चा हमने पहले श्रृंखला में की थी, उस तालिका व्यंजक पर लागू होती हैं जिस पर दृश्य आधारित है। एक अनुस्मारक के रूप में, आवश्यकताएं हैं:
- टेबल एक्सप्रेशन के सभी कॉलम के नाम होने चाहिए
- टेबल एक्सप्रेशन के सभी कॉलम नाम अद्वितीय होने चाहिए
- टेबल एक्सप्रेशन की पंक्तियों का कोई क्रम नहीं है
यदि आपको इन आवश्यकताओं के पीछे की अपनी समझ को ताज़ा करने की आवश्यकता है, तो श्रृंखला के भाग 2 में "एक तालिका अभिव्यक्ति एक तालिका है" अनुभाग देखें। सुनिश्चित करें कि आप विशेष रूप से "नो ऑर्डर" भाग को समझते हैं। एक संक्षिप्त अनुस्मारक के रूप में, एक तालिका अभिव्यक्ति एक तालिका है, और इस तरह कोई आदेश नहीं है। इसलिए आप ORDER BY क्लॉज वाली क्वेरी के आधार पर तब तक व्यू नहीं बना सकते, जब तक कि यह क्लॉज किसी TOP या OFFSET-FETCH फ़िल्टर को सपोर्ट करने के लिए न हो। और यहां तक कि इस अपवाद के साथ आंतरिक क्वेरी को क्लॉज द्वारा ऑर्डर करने की इजाजत है, आप याद रखना चाहते हैं कि यदि दृश्य के खिलाफ बाहरी क्वेरी का अपना ऑर्डर द्वारा क्लॉज नहीं है, तो आपको गारंटी नहीं मिलती है कि क्वेरी वापस आ जाएगी किसी विशेष क्रम में पंक्तियाँ, देखे गए व्यवहार पर कभी ध्यान न दें। यह समझना अति आवश्यक है!
नेस्टिंग और एकाधिक संदर्भ
व्युत्पन्न तालिकाओं और सीटीई के डिजाइन विचारों पर चर्चा करते समय, मैंने दोनों की तुलना नेस्टिंग और कई संदर्भों के संदर्भ में की। अब देखते हैं कि इन विभागों में व्यूज कैसा रहता है। मैं घोंसले के शिकार के साथ शुरू करूँगा। इस उद्देश्य के लिए, हम उस कोड की तुलना करेंगे जो उन वर्षों को लौटाता है जिसमें 70 से अधिक ग्राहकों ने व्युत्पन्न तालिकाओं, सीटीई और विचारों का उपयोग करके ऑर्डर दिया था। आप श्रृंखला में पहले ही व्युत्पन्न तालिकाओं और CTE के साथ कोड देख चुके हैं। यहां वह कोड है जो व्युत्पन्न तालिकाओं का उपयोग करके कार्य को संभालता है:
आदेश वर्ष चुनें, क्रमांक चुनें (आदेश वर्ष चुनें, COUNT(DISTINCT custid) अंक के रूप में (आदेश वर्ष (आदेश दिनांक) के रूप में, बिक्री से संरक्षक के रूप में चुनें।मैंने बताया कि व्युत्पन्न तालिकाओं के साथ मुझे जो मुख्य नकारात्मक पहलू दिखाई देता है, वह यह है कि आप व्युत्पन्न तालिका परिभाषाओं को घोंसला बनाते हैं, और इससे ऐसे कोड को समझने, बनाए रखने और समस्या निवारण में जटिलता हो सकती है।
यहाँ वह कोड है जो CTE का उपयोग करके समान कार्य को संभालता है:
सी1 एएस के साथ (सेलेक्ट ईयर (ऑर्डरडेट) ऑर्डर ईयर के रूप में, सेल्स से कस्टिड। ऑर्डर), सी 2 एएस (सेलेक्ट ऑर्डर ईयर, काउंट (डिस्टिंक्ट कस्टिड) के रूप में सी 1 ग्रुप से ऑर्डर ईयर) सेलेक्ट ऑर्डर ईयर, numcustsF2C2WHERE numcusts> 70;मैंने बताया कि मेरे लिए यह घोंसले की कमी के कारण बहुत स्पष्ट कोड जैसा लगता है। आप समाधान में प्रत्येक चरण को शुरू से अंत तक अलग-अलग अपनी इकाई में देख सकते हैं, जिसमें समाधान का तर्क ऊपर से नीचे तक स्पष्ट रूप से बहता है। इसलिए, मैं सीटीई विकल्प को इस संबंध में व्युत्पन्न तालिकाओं में सुधार के रूप में देखता हूं।
अब देखने के लिए। याद रखें, विचारों के मुख्य लाभों में से एक पुन:प्रयोज्य है। आप एक्सेस अनुमतियों को भी नियंत्रित कर सकते हैं। शामिल इकाइयों का विकास इस अर्थ में सीटीई के समान थोड़ा अधिक है कि आप अपना ध्यान एक समय में एक इकाई पर शुरू से अंत तक केंद्रित कर सकते हैं। इसके अलावा, आपके पास यह तय करने की सुविधा है कि समाधान में प्रति यूनिट एक अलग दृश्य बनाना है या नहीं, या शायद एक क्वेरी के आधार पर केवल एक दृश्य जिसमें स्टेटमेंट-स्कोप नामित टेबल एक्सप्रेशन शामिल हैं।
आप पूर्व के साथ जाएंगे जब प्रत्येक इकाई को पुन:प्रयोज्य करने की आवश्यकता होगी। यहां वह कोड है जिसका उपयोग आप ऐसे मामले में करेंगे, जिससे तीन दृश्य बनेंगे:
-- Sales.OrderYearsक्रिएट या ऑल्टर व्यू सेल्स।आदेशवर्षों के रूप में चुनें वर्ष(आदेश की तारीख) ऑर्डर वर्ष के रूप में, बिक्री से अभिरक्षक। बिक्री से।आदेशवर्ष समूह द्वाराआदेशवर्ष;जाओ - बिक्री।वार्षिक ग्राहक गणनाMin70बनाएँ या बिक्री देखें।वार्षिक ग्राहकगण 70AS से अधिक का चयन करेंआदेश वर्ष, बिक्री से अंक।वार्षिक ग्राहक गणनाएँ जहाँ numcusts> 70;GOआप प्रत्येक दृश्य को स्वतंत्र रूप से क्वेरी कर सकते हैं, लेकिन यहां वह कोड है जिसका उपयोग आप मूल कार्य के बाद वापस करने के लिए करेंगे।
आदेश का चयन करेंवर्ष, बिक्री से numcusts.YearlyCustCountsAbove70;यदि केवल सबसे बाहरी भाग (जो मूल कार्य की आवश्यकता है) के लिए पुन:प्रयोज्य आवश्यकता है, तो तीन अलग-अलग विचारों को विकसित करने की कोई वास्तविक आवश्यकता नहीं है। आप CTE या व्युत्पन्न तालिकाओं वाली क्वेरी के आधार पर एक दृश्य बना सकते हैं। सीटीई से जुड़े एक प्रश्न के साथ आप ऐसा कैसे करेंगे:
बिक्री बनाएं या बदलें। C1 AS के साथ वार्षिक ग्राहक गणना 70AS से ऊपर (आदेश वर्ष के रूप में चुनें (आदेश दिनांक) आदेश वर्ष के रूप में, बिक्री से संरक्षक। , C2 से numcusts जहां numcusts> 70;GOवैसे, यदि यह स्पष्ट नहीं था, तो दृश्य की आंतरिक क्वेरी पर आधारित CTE पुनरावर्ती हो सकते हैं।
आइए उन मामलों पर आगे बढ़ते हैं जहां आपको बाहरी क्वेरी से एक ही तालिका अभिव्यक्ति के लिए कई संदर्भों की आवश्यकता होती है। इस उदाहरण के लिए कार्य प्रति वर्ष वार्षिक आदेश गणना की गणना करना है, और प्रत्येक वर्ष में पिछले वर्ष के साथ गणना की तुलना करना है। इसे प्राप्त करने का सबसे आसान तरीका वास्तव में LAG विंडो फ़ंक्शन का उपयोग करना है, लेकिन हम तीन टूल के बीच एक बहु-संदर्भ मामले की तुलना करने के लिए वार्षिक ऑर्डर काउंट का प्रतिनिधित्व करने वाले टेबल एक्सप्रेशन के दो उदाहरणों के बीच एक जुड़ाव का उपयोग करेंगे।
यह वह कोड है जिसका उपयोग हमने श्रृंखला में पहले व्युत्पन्न तालिकाओं के साथ कार्य को संभालने के लिए किया था:
CUR.orderyear, CUR.numorders, CUR.numorders चुनें - PRV.numorders as diffFROM (चुनें वर्ष (आदेश दिनांक) ऑर्डर वर्ष के रूप में, COUNT (*) बिक्री से संख्या के रूप में। वर्ष द्वारा आदेश समूह (आदेश दिनांक)) CUR LEFT के रूप में आउटर जॉइन (चुनें वर्ष (आदेश दिनांक) ऑर्डर वर्ष के रूप में, COUNT (*) बिक्री से संख्याओं के रूप में। वर्ष द्वारा ऑर्डर समूह (आदेश दिनांक)) CUR पर पीआरवी के रूप में। आदेश वर्ष =पीआरवी.आदेश वर्ष + 1;यहाँ एक बहुत स्पष्ट नकारात्मक पहलू है। आपको टेबल एक्सप्रेशन की परिभाषा को दो बार दोहराना होगा। आप अनिवार्य रूप से एक ही क्वेरी कोड के आधार पर दो नामित तालिका अभिव्यक्तियों को परिभाषित कर रहे हैं।
यहाँ वह कोड है जो CTE का उपयोग करके समान कार्य को संभालता है:
ऑर्डकाउंट एएस के साथ (सेलेक्ट ईयर (ऑर्डरडेट) ऑर्डर ईयर के रूप में, काउंट (*) सेल्स से नंबर के रूप में। ऑर्डर ग्रुप बाय ईयर (ऑर्डरडेट)) सेलेक्ट सीयूआर.ऑर्डर ईयर, सीयूआर.नंबर्स, सीयूआर.नंबर्स - पीआरवी। CUR LEFT OUTER के रूप में OrdCount CUR.orderyear =PRV.orderyear + 1;पर पीआरवी के रूप में ऑर्डकाउंट में शामिल होंयहाँ एक स्पष्ट लाभ है; आप आंतरिक क्वेरी के एकल उदाहरण के आधार पर केवल एक नामित तालिका अभिव्यक्ति को परिभाषित करते हैं, और इसे बाहरी क्वेरी से दो बार संदर्भित करते हैं।
इस अर्थ में दृश्य सीटीई के समान अधिक हैं। आप क्वेरी की केवल एक प्रति के आधार पर केवल एक दृश्य को परिभाषित करते हैं, जैसे:
बिक्री बनाएं या बदलें।वार्षिक आदेशगणना वर्ष (आदेश दिनांक) के रूप में चुनें, आदेश वर्ष के रूप में, COUNT(*) बिक्री से संख्याओं के रूप में। वर्ष के अनुसार आदेश समूह(आदेश दिनांक);जाओलेकिन सीटीई से बेहतर, आप केवल बाहरी विवरण में नामित तालिका अभिव्यक्ति का पुन:उपयोग करने तक ही सीमित नहीं हैं। जब तक आपके पास सही अनुमतियाँ हों, तब तक आप कितनी भी बार असंबंधित प्रश्नों के साथ, जितनी बार चाहें, दृश्य नाम का पुन:उपयोग कर सकते हैं। दृश्य के कई संदर्भों का उपयोग करके कार्य को प्राप्त करने के लिए कोड यहां दिया गया है:
चुनें CUR.orderyear, CUR.numorders, CUR.numorders - PRV.numorders जैसा कि बिक्री से भिन्न होता है।YearlyOrderCounts as CUR LEFT OUTER JOIN Sales.YearlyOrderCur.orderyear =PRV.orderyear + 1;पर PRV के रूप में गणना करता है।ऐसा लगता है कि दृश्य व्युत्पन्न तालिकाओं की तुलना में सीटीई के समान हैं, अनुमतियों को नियंत्रित करने की क्षमता के साथ अधिक पुन:प्रयोज्य उपकरण होने की अतिरिक्त कार्यक्षमता के साथ। या इसे चारों ओर मोड़ने के लिए, सीटीई के बारे में कथन-दायरे वाले दृश्य के रूप में सोचना शायद उचित है। अब जो वास्तव में अद्भुत हो सकता है वह यह है कि यदि हमारे पास एक नामित तालिका अभिव्यक्ति भी है जो एक सीटीई की तुलना में व्यापक दायरे के साथ है, एक दृश्य की तुलना में संकुचित है। उदाहरण के लिए, क्या यह बहुत अच्छा नहीं होता अगर हमारे पास एक सत्र-स्तरीय स्कोप नामित टेबल एक्सप्रेशन होता?
सारांश
मुझे यह विषय पसंद है। तालिका के भावों में बहुत कुछ है जो संबंधपरक सिद्धांत में निहित है, जो बदले में गणित में निहित है। मुझे यह जानना अच्छा लगता है कि चीजों के लिए सही शर्तें क्या हैं, और आम तौर पर यह सुनिश्चित करना कि मेरे पास नींव सावधानी से समझी गई है, भले ही कुछ लोगों को यह पसंद और अधिक पांडित्य की तरह लग सकता है। पिछले कुछ वर्षों में अपनी सीखने की प्रक्रिया को देखते हुए, मैं नींव की अच्छी समझ पर जोर देने, सही शब्दावली का उपयोग करने, और वास्तव में आपकी सामग्री को बाद में जानने के बीच एक बहुत ही स्पष्ट मार्ग देख सकता हूं जब यह अधिक उन्नत और जटिल सामग्री तक पहुंच जाता है।पी>
तो, जब विचारों की बात आती है तो महत्वपूर्ण अंश क्या होते हैं?
- दृश्य एक तालिका है।
- यह एक टेबल है जो एक क्वेरी (एक टेबल एक्सप्रेशन) से ली गई है।
- इसे एक ऐसा नाम दिया गया है जो उपयोगकर्ता को एक टेबल नाम की तरह दिखाई देता है, क्योंकि यह एक टेबल नाम है।
- इसे डेटाबेस में एक स्थायी वस्तु के रूप में बनाया गया है।
- आप दृश्य के विरुद्ध एक्सेस अनुमतियों को नियंत्रित कर सकते हैं।
दृश्य कई मायनों में CTE के समान हैं। इस अर्थ में कि आप शुरू से अंत तक एक समय में एक इकाई पर ध्यान केंद्रित करते हुए अपने समाधान मॉड्यूलर तरीके से विकसित करते हैं। साथ ही इस अर्थ में कि आपके पास बाहरी क्वेरी से दृश्य नाम के कई संदर्भ हो सकते हैं। लेकिन सीटीई से बेहतर, विचार केवल बाहरी विवरण के दायरे तक ही सीमित नहीं हैं, बल्कि डेटाबेस से हटाए जाने तक पुन:प्रयोज्य हैं।
विचारों के बारे में कहने के लिए और भी बहुत कुछ है, और मैं अगले महीने चर्चा जारी रखूंगा। इस बीच, मैं आपको एक विचार के साथ छोड़ना चाहता हूं। व्युत्पन्न तालिकाओं और सीटीई के साथ आप एक आंतरिक क्वेरी में SELECT * के पक्ष में मामला बना सकते हैं। विवरण के लिए श्रृंखला के भाग 3 में मैंने इसके लिए जो मामला बनाया है, उसे देखें। क्या आप विचारों के साथ ऐसा ही मामला बना सकते हैं, या यह उनके साथ एक बुरा विचार है?