सबसे आम एसक्यूएल विरोधी पैटर्न क्या हैं? [बन्द है]


232

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


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

@casperOne कुछ "ऐतिहासिक महत्व" खंड नहीं है जो इस प्रश्न को स्वीकार्यता में दादा होगा?
एमी बी

26
मुझे यह दुखद लगता है कि वोहोल साइट पर सबसे उपयोगी प्रश्नों में से एक रचनात्मक के रूप में बंद है।
HLGEM

11
@HLGEM मैं पूरी तरह से सहमत हूँ। यह प्रश्न उन सभी का एक आदर्श उदाहरण है जो StackExchange
केविन मोर्स

1
विषय बिल्कुल महत्वपूर्ण और प्रासंगिक है। लेकिन सवाल बहुत खुला है, यही वजह है कि उत्तर प्रत्येक व्यक्ति के व्यक्तिगत विरोधी पैटर्न बगबियर का वर्णन कर रहे हैं।
शेन

जवाबों:


156

मैं अधिकांश यूजर्स की डेटा एक्सेस लेयर में उनके यूआई-लॉजिक को मिलाने की प्रवृत्ति से लगातार निराश हूं:

SELECT
    FirstName + ' ' + LastName as "Full Name",
    case UserRole
        when 2 then "Admin"
        when 1 then "Moderator"
        else "User"
    end as "User's Role",
    case SignedIn
        when 0 then "Logged in"
        else "Logged out"
    end as "User signed in?",
    Convert(varchar(100), LastSignOn, 101) as "Last Sign On",
    DateDiff('d', LastSignOn, getDate()) as "Days since last sign on",
    AddrLine1 + ' ' + AddrLine2 + ' ' + AddrLine3 + ' ' +
        City + ', ' + State + ' ' + Zip as "Address",
    'XXX-XX-' + Substring(
        Convert(varchar(9), SSN), 6, 4) as "Social Security #"
FROM Users

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

ऊपर दिखाए गए जैसे प्रश्न अत्यंत भंगुर हैं क्योंकि वे यूआई परत को डेटा परत को कसकर जोड़ते हैं। उसके शीर्ष पर, प्रोग्रामिंग की यह शैली संग्रहीत प्रक्रियाओं को पुन: प्रयोज्य होने से रोकती है।


10
स्तरों / अमूर्त परतों की सबसे बड़ी संख्या में अधिकतम युग्मन के लिए एक अच्छा पोस्टर-चाइल्ड पैटर्न।
dkretz

3
यह डी-कपलिंग के लिए अच्छा नहीं हो सकता है, हालांकि प्रदर्शन कारणों से मैंने इस तरह से सामान किया है, SQL सर्वर द्वारा किए गए पुनरावृत्ति परिवर्तन मध्य-स्तरीय में कोड द्वारा किए गए की तुलना में तेज़ हैं। मैं आपको पुन: प्रयोज्य बिंदु नहीं देता - सपा को चलाने और यदि आप चाहें तो कर्नल का नाम बदलने से कुछ भी नहीं रोकता है।
जो पाइंड

54
मेरा पसंदीदा है जब लोग HTML और जावास्क्रिप्ट एम्बेड करते हैं, उदाहरण के लिए '<a href=... onclick="">' + name '</a> </a> का चयन करें
मैट रोजिश

15
इस तरह के प्रश्नों के साथ, आप एक साधारण परिवर्तन कथन के साथ एक वेबसाइट में ग्रिड को संपादित कर सकते हैं। या एक रिपोर्ट में एक निर्यात की सामग्री, या सुधार की तारीख बदल दें। यह ग्राहकों को खुश करता है, और मुझे समय बचाता है। तो धन्यवाद, लेकिन कोई धन्यवाद नहीं, मैं इस तरह के प्रश्नों के साथ रहूँगा।
एंडोमर

4
@ मैट रोजिश - जीसस, वास्तव में कोई ऐसा करता है?
ऐक्सैरिडैक्स

118

यहाँ मेरे शीर्ष 3 हैं।

नंबर 1. फ़ील्ड सूची निर्दिष्ट करने में विफलता। (संपादित करें: भ्रम को रोकने के लिए: यह एक उत्पादन कोड नियम है। यह एकबारगी विश्लेषण लिपियों पर लागू नहीं होता है - जब तक कि मैं लेखक नहीं हूँ।)

SELECT *
Insert Into blah SELECT *

होना चाहिए

SELECT fieldlist
Insert Into blah (fieldlist) SELECT fieldlist

नंबर 2. कर्सर और लूप का उपयोग करते समय, जब लूप वेरिएबल के साथ थोड़ी देर में लूप होगा।

DECLARE @LoopVar int

SET @LoopVar = (SELECT MIN(TheKey) FROM TheTable)
WHILE @LoopVar is not null
BEGIN
  -- Do Stuff with current value of @LoopVar
  ...
  --Ok, done, now get the next value
  SET @LoopVar = (SELECT MIN(TheKey) FROM TheTable
    WHERE @LoopVar < TheKey)
END

संख्या 3. तार प्रकार के माध्यम से डेटॉलिक।

--Trim the time
Convert(Convert(theDate, varchar(10), 121), datetime)

होना चाहिए

--Trim the time
DateAdd(dd, DateDiff(dd, 0, theDate), 0)

मैंने हाल ही में देखा कि "एक क्वेरी दो, अमीर से बेहतर है?"

SELECT *
FROM blah
WHERE (blah.Name = @name OR @name is null)
  AND (blah.Purpose = @Purpose OR @Purpose is null)

इस क्वेरी को मापदंडों के मूल्यों के आधार पर दो या तीन अलग-अलग निष्पादन योजनाओं की आवश्यकता होती है। केवल एक निष्पादन योजना उत्पन्न होती है और इस sql पाठ के लिए कैश में अटक जाती है। उस योजना का उपयोग मापदंडों के मूल्य की परवाह किए बिना किया जाएगा। इससे आंतरायिक खराब प्रदर्शन होता है। दो प्रश्नों (एक क्वेरी प्रति इच्छित निष्पादन योजना) लिखना बेहतर है।


7
हम्म्, मैं आपको अंक 2 और 3 के लिए अकेले +1 दूंगा, लेकिन डेवलपर्स नियम 1 को ओवरले करते हैं। यह कभी-कभी होता है।
अन्नकूट

1
# 1 के पीछे क्या कारण है?
jalf 20

29
जब आप select * का उपयोग करते हैं, तो आपको टेबल में जो कुछ भी होता है वह मिलता है। वे कॉलम नाम और क्रम बदल सकते हैं। क्लाइंट कोड अक्सर नामों और ऑर्डर पर निर्भर करता है। हर 6 महीने में मुझे पूछा जाता है कि टेबल को संशोधित करते समय कॉलम ऑर्डर को कैसे संरक्षित किया जाए। यदि नियम का पालन किया गया तो यह कोई मायने नहीं रखेगा।
एमी बी

मैंने कभी-कभी # 2 का उपयोग किया है, अन्य मैं कर्सर मार्ग पर चला गया हूं (हालांकि तब मैं पहली बार तालिका के संस्करण पर क्वेरी के परिणामों को सहेजता हूं, उस पर कर्सर खोलें)। मुझे हमेशा आश्चर्य होता है कि क्या किसी ने दोनों का प्रदर्शन परीक्षण किया है।
जो पिनाडा

4
... लेकिन निश्चित रूप से कर्सर हमेशा सेट-आधारित एसक्यूएल के साथ काम करने में विफलता के बाद, लगभग हमेशा एक अंतिम उपाय होना चाहिए। मैंने एक बार एक संग्रहीत प्रक्रिया में एक भयावह, विशाल पीएल / एसक्यूएल कर्सर को ध्यान से विघटित करने में लगभग 45 मिनट बिताए, जो एक सड़ी हुई चीज़ के आकर्षित चित्र), जिसने एक बड़ी अस्थायी तालिका को पॉप्युलेट किया, फिर एक रेंडर करने के लिए कॉल करने के लिए वापस टेम्पर टेबल की सामग्री को चुना। रिपोर्ट good। पर्याप्त हार्डवेयर पर इसे चलाने में 8.5 मिनट का समय लगा। पूरी बात को आरेखित करने के बाद, मैं इसे एक एकल क्वेरी के साथ बदलने में सक्षम था जिसने 2 सेकंड के भीतर समान परिणाम लौटा दिए। कर्सर, आदमी ...
क्रेग

71
  • मानव पठनीय पासवर्ड फ़ील्ड , उदाहरण के लिए। स्वयं व्याख्यात्मक।

  • अनुक्रमित स्तंभों के विरुद्ध LIKE का उपयोग करना , और मैं लगभग केवल LIKE को सामान्य रूप से कहने के लिए लुभा रहा हूँ।

  • पुनर्चक्रण SQL- जनित PK मान।

  • आश्चर्य किसी ने अभी तक देव-तालिका का उल्लेख नहीं किया है। कुछ भी नहीं कहता है "कार्बनिक" जैसे 100 बिट्स के झंडे, बड़े तार और पूर्णांक।

  • फिर वहाँ "आई मिस .ini फाइल्स" पैटर्न है: सीएसवी, पाइप सीमांकित तार या अन्य पार्स आवश्यक डेटा को बड़े पाठ क्षेत्रों में संग्रहीत करना।

  • और MS SQL सर्वर के लिए कर्सर का उपयोग बिल्कुल भी नहीं है । किसी भी दिए गए कर्सर कार्य को करने का एक बेहतर तरीका है।

बहुत सारे होने के कारण संपादित!


19
शाप देने वालों के बारे में गलत, मैं किसी विशेष बात को कहने में संकोच करूंगा कि वह 100% सही है या 100% गलत है
Shawn

4
अब तक मैंने देखा है कि हर कर्सर रक्षा कार्य के लिए गलत टूल का उपयोग कर रहा है। लेकिन अगर आप सभी जानते हैं कि आप SQL हैं, तो आप इसे अनुचित तरीके से उपयोग करते हैं, या आप अन्य प्रकार के सॉफ़्टवेयर लिखना सीखते हैं।
dkretz

3
@tuinstoel: सूचकांक का उपयोग करने के लिए LIKE '% blah%' को कैसे प्राप्त होता है? अनुक्रमण आदेश देने पर निर्भर करता है और यह उदाहरण एक स्ट्रिंग की यादृच्छिक मध्य स्थिति को खोजता है। (1 वर्ण 1 द्वारा अनुक्रमित क्रम, और इसलिए मध्य 4 वर्णों को
देखना

12
अधिकांश डेटाबेस सर्वरों पर (कम से कम जिनका मैंने उपयोग किया है), LIKE अनुक्रमित का उपयोग कर सकते हैं .. जब तक कि यह एक उपसर्ग-खोज (LIKE 'xxx%') है - जब तक कि वाइल्डकार्ड वर्ण नहीं हैं खोज स्ट्रिंग में पहले आओ। मुझे लगता है कि आप यहाँ क्रॉस-प्रयोजनों में बात कर रहे होंगे।
कोवान

10
यह आपको पसंद नहीं है LIKE '%LIKE'
जोहान

62

इसके लिए गहरी खुदाई न करें: तैयार किए गए कथनों का उपयोग नहीं करना।


3
हाँ। मेरे अनुभव में, "नहीं फंसने वाली त्रुटियों" के साथ, उसी संदर्भ में बारीकी से अनुसरण किया गया।
dkretz

1
@stesch: यह विचारों का उपयोग करने और एक चर रिपोर्टिंग तिथि होने की तुलना में कुछ भी नहीं है। यदि आपके पास परिवर्तनशील रिपोर्टिंग तिथि है (मेरे पास अधिकांश अनुप्रयोग हैं, तो लगता है) दृश्य एक एंटीपैटर्न हैं। इसे एक अलग उत्तर में जोड़ देंगे, लेकिन यह दुर्भाग्य से बंद है।
स्टीफन स्टीगर

56

अर्थहीन तालिका का उपयोग करना

from employee t1,
department t2,
job t3,
...

एक बड़े एसक्यूएल स्टेटमेंट को पढ़ना इतना कठिन हो जाता है जितना कि उसे होना चाहिए


49
उपनाम? नरक मैंने वास्तविक कॉलम नाम देखे हैं जैसे
annakata

10
चंचल उपनाम OKAY हैं। यदि आप एक सार्थक नाम चाहते हैं तो एक उपनाम का उपयोग बिल्कुल भी न करें।
जोएल कोएहॉर्न

43
उन्होंने कहा कि "नहीं है", "उन्होंने कहा" अर्थहीन। मेरी पुस्तक में उदाहरण के प्रश्न में उपनाम के रूप में ई, डी और जे का उपयोग करने में कुछ भी गलत नहीं होगा।
रॉबर्ट रॉसनी

11
बिल्कुल, रॉबर्ट - ई, डी, और जे मेरे साथ ठीक होगा।
टोनी एंड्रयूज

8
मैं कर्मचारी के लिए
एम्पायर का उपयोग करूँगा

53
var query = "select COUNT(*) from Users where UserName = '" 
            + tbUser.Text 
            + "' and Password = '" 
            + tbPassword.Text +"'";
  1. उपयोगकर्ता इनपुट पर आँख बंद करके भरोसा करना
  2. पैरामीटर किए गए प्रश्नों का उपयोग नहीं करना
  3. पासवर्ड साफ़ करें

जिनमें से सभी को कुछ (किसी भी) प्रकार के डेटाबेस एब्स्ट्रैक्टन लेयर का उपयोग करके उपयोगी तरीके से निपटा जा सकता है।
dkretz

@doofledorfer: सहमत हूँ, इस तरह से एक मामले में एक मध्य स्तरीय निश्चित रूप से बेहतर होगा, साथ ही एक अच्छा प्रभाव प्रभाव के रूप में कैशिंग परिणाम प्रदान करता है।
जो पिनाडा

बहुत बढ़िया उदाहरण। यदि कोई देवता यह बताता है कि एक अच्छे समाधान के साथ कैसे प्रतिस्थापित किया जाए, तो वे एक सभ्य SQL देव बनने के लिए आधे रास्ते हैं।
स्टीव मैक्लोड

46

मेरे बगबियर्स 450 कॉलम एक्सेस टेबल हैं, जिन्हें मैनेजिंग डायरेक्टर के बेस्ट फ्रेंड्स डॉग ग्रूमर के 8 साल के बेटे और डॉगी लुकिंग टेबल ने एक साथ रखा है, जो केवल इसलिए मौजूद है क्योंकि किसी को यह पता नहीं है कि किसी डेटास्ट्रक्चर को कैसे ठीक किया जाए।

आमतौर पर, यह लुकअप तालिका कुछ इस प्रकार है:

मैंने नहीं किया,
नाम NVARCHAR (132),
IntValue1 INT,
IntValue2 INT,
CharValue1 NVARCHAR (255),
CharValue2 NVARCHAR (255),
दिनांक 1 तिथि,
दिनांक २ तारीख

मैंने उन ग्राहकों की संख्या खो दी है जिन्हें मैंने देखा है जिनके पास ऐसे सिस्टम हैं जो इस तरह के घृणा पर भरोसा करते हैं।


1
इससे भी बदतर, मैंने पढ़ा है कि एक्सेस के नवीनतम संस्करण में वास्तव में स्वचालित रूप से समर्थन किया गया है, जो मुझे डर है कि मैं इस वैल्यू 1, वैल्यू 2, वैल्यू 3 ... कॉलम भ्रूणवाद को और अधिक प्रोत्साहित करूंगा
जो Pineda

रुको - तो 8 साल का बेटा कुत्ते के दूल्हे का बेटा है?
बैरीपिकार

28

जो मुझे सबसे ज्यादा नापसंद हैं वो हैं

  1. टेबल, स्प्रोक्स इत्यादि बनाते समय रिक्त स्थान का उपयोग करना। मैं CamelCase या under_scores और एकवचन या बहुवचन या UPPERCASE या लोअरकेस के साथ ठीक हूं लेकिन किसी तालिका या स्तंभ को संदर्भित करने के लिए [विशेष रूप से रिक्त स्थान के साथ], [हाँ मैंने इसमें भाग लिया) वास्तव में मुझे परेशान करता है।

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

  3. विचारों या अभिशापों का अति प्रयोग। दृश्यों का एक उद्देश्य है, लेकिन जब प्रत्येक तालिका को एक दृश्य में लपेटा जाता है तो यह बहुत अधिक होता है। मुझे कुछ बार कर्सर का उपयोग करना पड़ा है, लेकिन आम तौर पर आप इसके लिए अन्य तंत्र का उपयोग कर सकते हैं।

  4. पहुंच। क्या कोई कार्यक्रम एक प्रतिमान हो सकता है? हमारे काम में हमारे पास SQL ​​सर्वर है, लेकिन यह उपलब्ध होने के कारण कई लोग पहुंच का उपयोग करते हैं, गैर-तकनीकी उपयोगकर्ताओं के लिए "उपयोग में आसानी" और "मित्रता"। यहाँ जाने के लिए बहुत कुछ है, लेकिन यदि आप एक समान वातावरण में हैं, तो आप जानते हैं।


2
# 4 - <a href=' stackoverflow.com/questions/327199/…> :) के लिए एक और धागा है ।
dkretz

4
प्रवेश एक DBMS नहीं है। यह एक बहुत ही सरल डेटाबेस प्रबंधक के साथ, एक रेड वातावरण है। SQL सर्वर, Oracle, et al। जब तक आप VB जैसी भाषा और क्रिस्टल रिपोर्ट जैसी सुविधा नहीं जोड़ते, तब तक इसे प्रतिस्थापित नहीं किया जाएगा ।
जो पिनाडा

26

SP को स्टोर प्रक्रिया नाम के उपसर्ग के रूप में उपयोग करें क्योंकि यह पहले कस्टम प्रक्रियाओं के बजाय सिस्टम प्रक्रियाओं के स्थान पर खोज करेगा।


1
सभी संग्रहीत प्रक्रियाओं के लिए किसी भी अन्य सामान्य उपसर्ग का उपयोग करने के लिए भी बढ़ाया जा सकता है, जिससे छंटनी सूची के माध्यम से चुनना अधिक कठिन हो जाता है।
dkretz

7
Doofledorfer टिप्पणी के लिए +1 !! मैंने इसे बहुत देखा है, मुझे यह मूर्खतापूर्ण लगता है और वास्तव में किसी विशेष सपा की खोज करना बहुत मुश्किल है !!! विचारों के लिए "vw_" तक भी विस्तारित, तालिकाओं और जैसे, "tbl_" के लिए मैं कैसे उनसे नफरत करता हूं!
जो पिनाडा

1
उपसर्ग उपयोगी हो सकते हैं यदि आप फ़ाइलों को ऑब्जेक्ट्स को स्क्रिप्ट कर रहे हैं (जैसे: स्रोत नियंत्रण, परिनियोजन या माइग्रेशन के लिए)
रिक

1
पृथ्वी पर sp या usp के साथ हर एक संग्रहीत प्रक्रिया को उपसर्ग करना उपयोगी क्यों होगा ? यह सिर्फ उस सूची को स्कैन करना कठिन बनाता है जिसे आप चाहते हैं।
रयान ल्यूडी

25

अस्थायी तालिकाओं और कर्सर का अति प्रयोग।


2
अच्छा सबूत है कि "मुझे पता है कि सभी प्रक्रियात्मक भाषाएँ हैं"।
dkretz

2
किसी भी चीज का अत्यधिक उपयोग करना अवांछित है। अस्थायी तालिकाओं / श्रापों का उपयोग करने की आवश्यकता नहीं है, जहां एक विशिष्ट उदाहरण सहायक होगा।
जेक रिया

6
ज्यादातर मैं अस्थायी टेबल्स को अंडर-यूज़ किया हुआ देखता हूँ। SQL सर्वर के साथ अक्सर आप एक अखंड क्वेरी के बजाय अस्थायी तालिकाओं के एक समूह के साथ सामान करके प्रदर्शन लाभ प्राप्त करते हैं।
Cervo

24

समय मूल्यों को संग्रहीत करने के लिए, केवल यूटीसी टाइमज़ोन का उपयोग किया जाना चाहिए। स्थानीय समय का उपयोग नहीं किया जाना चाहिए।


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

1
@CongorHalmai कई जगह दिन के उजाले की बचत का अभ्यास करते हैं, इसलिए समय बदलाव के एक घंटे के भीतर समय मान अस्पष्ट हो सकता है।
फ्रैंक श्वेटरमैन

यह निश्चित रूप से वर्तमान और अतीत के लिए सही है, लेकिन भविष्य के लिए, विशेष रूप से काफी दूर के भविष्य के लिए, स्पष्ट समय क्षेत्र अक्सर एक आवश्यकता है। यदि आपके पास 30-वर्षीय विकल्प है जो अभी लिखा गया था और 2049-09-27T17: 00: 00 न्यू यॉर्क समय में समाप्त हो रहा है, तो आप केवल आँख मूंदकर यह अनुमान नहीं लगा सकते कि यह 21: 00: 00Z होगा। अमेरिकी कांग्रेस डीएसटी नियमों को अच्छी तरह से बदल सकती है। आपको स्थानीय समय और सही समय क्षेत्र (अमेरिका / न्यू_यॉर्क) को अलग रखना होगा।
जॉन कोवान

23

SCOPE_IDENTITY () के बजाय @@ पहचान का उपयोग करना

इस उत्तर से उद्धृत :

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

+1 बहुत सही, एक ऐसे कीड़े का कारण बन सकता है जो खरपतवार के लिए कठिन होगा
Axarydax

23

कुछ के लिए एक 'मृत' क्षेत्र का फिर से उपयोग करना जिसका उद्देश्य नहीं था (जैसे 'फ़ैक्स' फ़ील्ड में उपयोगकर्ता डेटा संग्रहीत करना) - हालांकि एक त्वरित फ़िक्स के रूप में बहुत लुभावना!


21
select some_column, ...
from some_table
group by some_column

और यह मानते हुए कि परिणाम some_column द्वारा क्रमबद्ध किया जाएगा। मैंने इसे Sybase के साथ थोड़ा देखा है जहाँ धारणा (अभी के लिए) है।


1
ईवीआर के लिए क्रमबद्ध रूप से क्रमबद्ध करें, सिर्फ इसलिए कि यह जिस तरह से क्वेरी टूल में दिखाया गया था कि एक बार
जोएल कोएहॉर्न

3
मैंने इसे एक बार से अधिक बग के रूप में रिपोर्ट किया है।
dkretz

6
MySQL में, इसे सॉर्ट करने के लिए प्रलेखित किया गया है। < dev.mysql.com/doc/refman/5.0/en/select.html >। इसलिए MySQL (फिर से) को दोष दें।
अपमानजनक

1
ओरेकल में, अनसाल्टेड परिणाम (लगभग) हमेशा ग्रुपिंग से मेल खाते थे - संस्करण 10 जी तक। डेवलपर्स के लिए बहुत सारे काम जो ऑर्डर्स बाय को छोड़ देते थे!
टोनी एंड्रयूज

1
मैं एक प्रशिक्षण वर्ग में भी था जहाँ यह SQL सर्वर के लिए एक तथ्य के रूप में कहा गया था। मुझे वास्तव में जोर से विरोध करना पड़ा। केवल 20 वर्णों को सहेजने के लिए आप अस्पष्ट या अनिर्दिष्ट व्यवहार पर भरोसा करते हैं।
एरिक्कलेन

20
SELECT FirstName + ' ' + LastName as "Full Name", case UserRole when 2 then "Admin" when 1 then "Moderator" else "User" end as "User's Role", case SignedIn when 0 then "Logged in" else "Logged out" end as "User signed in?", Convert(varchar(100), LastSignOn, 101) as "Last Sign On", DateDiff('d', LastSignOn, getDate()) as "Days since last sign on", AddrLine1 + ' ' + AddrLine2 + ' ' + AddrLine3 + ' ' + City + ', ' + State + ' ' + Zip as "Address", 'XXX-XX-' + Substring(Convert(varchar(9), SSN), 6, 4) as "Social Security #" FROM Users

या, एक लाइन में सब कुछ cramming।


पिछली टिप्पणी की क्वेरी का उपयोग किया, सिर्फ इसलिए कि यह पहला एसक्यूएल-स्टेटमेंट था जो मैंने उपलब्ध किया था।
जैस्पर बेकर्स

17
  • FROM TableA, TableB WHEREवाक्य विन्यास के बजाय कार्यभार संभालाFROM TableA INNER JOIN TableB ON

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


5
मेरा ओरेकल डीबीए हमेशा शिकायत करता है कि मैं "एएनएसआई जॉइन" का उपयोग करता हूं, अर्थात, आप सही तरीके से क्या प्रस्तुत करते हैं। लेकिन मैं यह कर रहा हूं, और मुझे संदेह है कि वे गहराई से इसके बेहतर तरीके को जानते हैं।
स्टीव मैक्लोड

1
मुझे संदेह है कि ओरेकल की इच्छा मानक एसक्यूएल चली जाएगी। :-) इसके अलावा, आप MySQL 5 में निहित और स्पष्ट JOINS (उर्फ ANSI JOIN) नहीं मिला सकते हैं - यह काम नहीं करता है। जो स्पष्ट JIONs के लिए एक और तर्क है।
स्टेटिक्सन

3
मैं यह भी कहूंगा कि A INNER JOIN B ON एक एंटी पैटर्न है। मैं एक ININ JOIN B USING पसंद करता हूं।
जॉन निल्सन

ओरेकल अब एएनएसआई सिंटैक्स का समर्थन करता है, लेकिन वे अतीत में बाहरी जोड़ों के लिए यह वास्तव में अजीब सिंटैक्स होते थे और अभी भी बहुत से लोग इसका उपयोग कर रहे हैं।
Cervo

अच्छा ... ओरेकल अभी भी आपको एएनएसआई ज्वाइन
कमिटेड

14

अपने करियर के पहले छह महीनों में एसक्यूएल सीखना और अगले 10 वर्षों तक कभी और कुछ नहीं सीखना। विशेष रूप से विंडोिंग / विश्लेषणात्मक एसक्यूएल सुविधाओं का उपयोग करते हुए सीखने या प्रभावी ढंग से नहीं। विशेष रूप से ओवर () और विभाजन का उपयोग।

विंडो फ़ंक्शंस, जैसे कुल फ़ंक्शंस, पंक्तियों के एक निर्धारित सेट (एक समूह) पर एक एकत्रीकरण करते हैं, लेकिन प्रति समूह एक मान वापस करने के बजाय, विंडो फ़ंक्शंस प्रत्येक समूह के लिए कई मान वापस कर सकते हैं।

विंडो कार्यों के एक अच्छे अवलोकन के लिए ओ'रिली एसक्यूएल कुकबुक परिशिष्ट ए देखें ।


12

मुझे यहां अपना वर्तमान पसंदीदा बनाने की जरूरत है, बस सूची को पूरा करने के लिए। मेरा पसंदीदा एंटीपाटन है आपके प्रश्नों का परीक्षण नहीं कर रहा है

यह तब लागू होता है जब:

  1. आपकी क्वेरी में एक से अधिक तालिकाएँ शामिल हैं।
  2. आपको लगता है कि आपके पास क्वेरी के लिए एक इष्टतम डिज़ाइन है, लेकिन अपनी मान्यताओं का परीक्षण करने की जहमत नहीं उठानी चाहिए।
  3. आप पहली क्वेरी को स्वीकार करते हैं, जिसमें कोई सुराग नहीं है कि क्या यह अनुकूलित के करीब है।

और कोई भी परीक्षण atypical या अपर्याप्त डेटा के विरुद्ध नहीं चलते हैं। यदि यह एक संग्रहीत प्रक्रिया है, तो परीक्षण विवरण को एक टिप्पणी में रखें और परिणामों के साथ इसे सहेजें। अन्यथा, इसे परिणामों के साथ कोड में एक टिप्पणी में डालें।


न्यूनतम T-SQL परीक्षण के लिए एक बहुत ही उपयोगी तकनीक: .SQL फ़ाइल में जहाँ आप अपने SP, UDF इत्यादि को परिभाषित करते हैं, इसके तुरंत बाद IF 1 = 2 BEGIN जैसे ब्लॉक टेस्ट बनाते हैं (आपके कोड के लिए नमूना मामले, अपेक्षित परिणामों के साथ) टिप्पणियों के रूप में) END
जो Pineda

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

वास्तविक डेटा के साथ परीक्षण करना हमेशा संभव नहीं होता है। अक्सर देव सर्वर / "परीक्षण" सर्वर अंडरपेड है और लाइव सर्वर का एक अंश प्राप्त करता है। आम तौर पर परीक्षण को लाइव सर्वर के खिलाफ दिखाया जाता है। कुछ स्थान बेहतर हैं और लाइव डेटा के साथ एक परीक्षण या मंचन सर्वर है।
Cervo

11

अस्थायी तालिका का दुरुपयोग।

विशेष रूप से इस तरह की बात:

SELECT personid, firstname, lastname, age
INTO #tmpPeople
FROM People
WHERE lastname like 's%'

DELETE FROM #tmpPeople
WHERE firstname = 'John'

DELETE FROM #tmpPeople
WHERE firstname = 'Jon'

DELETE FROM #tmpPeople
WHERE age > 35

UPDATE People
SET firstname = 'Fred'
WHERE personid IN (SELECT personid from #tmpPeople)

क्वेरी से एक अस्थायी तालिका का निर्माण न करें, केवल उन पंक्तियों को हटाने के लिए जिनकी आपको आवश्यकता नहीं है।

और हां, मैंने उत्पादन डीबी में इस रूप में कोड के पेज देखे हैं।


1
+1, मैं सहमत हूं। हालांकि, मुझे कम से कम एक या दो मामले मिले हैं जहां इस तकनीक ने प्रदर्शन में सुधार किया है - इसमें शामिल प्रश्न कम से कम कहने के लिए जटिल थे।
a'r

1
सच है - उनके पास एक जगह है, बस हर क्वेरी में नहीं :)
geofftnz

1
कभी-कभी आपको यह करना होगा कि यदि स्थितियां जटिल हैं। सही है कि इसका दुरुपयोग चरम सीमा तक किया जा सकता है। लेकिन कई बार एक साधारण डिलीट प्रारंभिक क्वेरी में केस प्राप्त करने के लिए तर्क की तुलना में बहुत सरल है। इसके अलावा कभी-कभी यदि क्लॉज़ सररिट नहीं होता है तो प्रारंभिक क्वेरी धीमी हो जाएगी। लेकिन बस इसे छोटे टेम्प टेबल पर करना अधिक कुशल है। और अन्य बार आप ऐसे मामलों को जोड़ते रहते हैं जो व्यवसाय के लोग इस तथ्य के बाद जोड़ते रहते हैं।
Cervo

9

विपरीत दृष्टिकोण: सामान्यीकरण के साथ अति-जुनून।

अधिकांश SQL / RBDBs सिस्टम एक से कई सुविधाएँ (लेन-देन, प्रतिकृति) देते हैं, जो अप्राकृतिक डेटा के साथ भी काफी उपयोगी हैं। डिस्क स्थान सस्ता है, और कभी-कभी यह डेटा को हेरफेर / फ़िल्टर / खोज करने के लिए सरल (आसान कोड, तेज विकास समय) हो सकता है, क्योंकि यह 1NF स्कीमा को लिखने के लिए है, और इसमें सभी परेशानियों से निपटना है (जटिल जुड़ाव, गंदे सबसेलेक्ट्स , आदि)।

मैंने पाया है कि अति-सामान्यीकृत प्रणाली अक्सर समय से पहले अनुकूलन होती है, खासकर शुरुआती विकास चरणों के दौरान।

(इस पर और विचार ... http://writeonly.wordpress.com/2008/12/05/simple-object-db-use-json-and-python-sqlite/ )


22
मुझे लगता है कि गैर-सामान्यीकरण अक्सर समय से पहले अनुकूलन है।
tuinstoel

कभी कभी यह है, कभी कभी यह नहीं है। सौभाग्य से, यह अक्सर परीक्षण करना आसान होता है, और विभिन्न विकल्प अलग-अलग डीबी आवश्यकताओं के साथ काम करते हैं।
ग्रेग लिंड

17
सामान्यीकरण केवल डिस्क स्थान की बचत के लिए नहीं है। यह डेटा के लिए एक आधिकारिक स्रोत भी बनाना है। यदि डेटा को केवल एक ही स्थान पर संग्रहीत किया जाता है, तो संगतता सावधान कोडिंग का बायप्रोडक्ट नहीं है, बल्कि इसके बजाय डिजाइन का एक बायप्रोडक्ट है।
ग्रांट जॉनसन

JSON प्रारूप में यौगिक डेटा संग्रहीत करना एक बात है: इसके लिए अधिक से अधिक समर्थन है, और यह एक सचेत व्यापार है। किसी से जुड़ने की कोशिश में अल्पविराम से अलग किए गए (या जो भी) मूल्यों का उपयोग करना पैनी समझदारी और पाउंड-मूर्खता है।
जॉन कोवान

noSQL समाधान मल्टी-टेबल लुकअप को समाप्त करके डुप्लिकेट डेटा की कीमत पर प्रदर्शन लाभ दिखा रहे हैं। अपने सिर पर पूरी तरह से सामान्यीकरण चीज़ डालता है। कुछ उदाहरणों में एक प्रक्रिया सुनिश्चित करने के लिए डेटा को कई स्थानों पर एकत्र किया जाता है, जिसमें सबसे तेज़ प्रतिक्रिया समय संभव है। बेशक, आधिकारिक स्रोतों के बारे में सवाल खेलने के लिए आते हैं।
बैरीपिकर

9

मैं इसे एसओ पर यहाँ एसक्यूएल प्रतिक्रियाओं में से कुछ के आधार पर एक साथ रखता हूं।

यह सोचने के लिए एक गंभीर एंटीपैटर्न है कि ट्रिगर डेटाबेस के लिए हैं क्योंकि इवेंट हैंडलर ओओपी के लिए हैं। इस धारणा है कि किसी भी पुराने तर्क को ट्रिगर में डाल दिया जा सकता है, जब एक मेज पर लेनदेन (घटना) होता है।

सच नहीं। बड़े अंतरों में से एक यह है कि ट्रिगर समकालिक हैं - प्रतिशोध के साथ, क्योंकि वे एक सेट ऑपरेशन पर सिंक्रोनस हैं, न कि एक पंक्ति ऑपरेशन पर। OOP की तरफ, बिल्कुल विपरीत - घटनाएं अतुल्यकालिक लेनदेन को लागू करने का एक प्रभावी तरीका है।


8

बिना किसी टिप्पणी के संग्रहीत कार्यविधियाँ या कार्य ...


और विचार;) तालिका-मूल्यवान कार्यों (= मापदंडों के साथ विचार) को छोड़कर कार्य सच है।
स्टीफन स्टेगर

7

1) मुझे नहीं पता कि यह एक "आधिकारिक" विरोधी पैटर्न है, लेकिन मैं नापसंद करता हूं और डेटाबेस कॉलम में जादुई मूल्यों के रूप में स्ट्रिंग शाब्दिक से बचने की कोशिश करता हूं।

मीडियाविकि की तालिका 'छवि' से एक उदाहरण:

img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", 
    "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
img_major_mime ENUM("unknown", "application", "audio", "image", "text", 
    "video", "message", "model", "multipart") NOT NULL default "unknown",

(मैं बस अलग आवरण नोटिस, एक और बात से बचने के लिए)

मैं ऐसे मामलों को सारणी में देखता हूं जैसे कि ImageMediaType और ImageMajorMime में प्राथमिक प्राथमिक कुंजियों के साथ।

2) दिनांक / स्ट्रिंग रूपांतरण जो विशिष्ट एनएलएस सेटिंग्स पर निर्भर करता है

CONVERT(NVARCHAR, GETDATE())

प्रारूप पहचानकर्ता के बिना


और कोई वाक्यगत इंडेंटेशन भी नहीं। Argghh।
dkretz

2
यह बुरा क्यों है? निश्चित रूप से यदि आप मानों के एक सेट को व्यक्त करने की कोशिश कर रहे हैं तो यह एक लुकअप टेबल के साथ ही काम करता है, और इसे कॉल करने वाले कोड के साथ बेहतर रूप से फिट बैठता है। आईडी के बजाय मेरे ऐप कोड में एक एनम है जो मेरे डीबी में एक एनम बाधा के लिए मैप करता है जो मेरे ऐप कोड में एनम की तुलना में है जो लुकअप टेबल की विशिष्ट पंक्तियों पर मैप करता है। यह सिर्फ क्लीनर लगता है।
जैक रयान

@JackRyan: यह बुरा है क्योंकि जब आप बाद में enum सूची को बदलते हैं, तो आपको इसे अब दो स्थानों पर बदलने के लिए याद रखना होगा। यह DRY का उल्लंघन करता है । डेटाबेस सत्य का एकल स्रोत होना चाहिए।
गेरेट

7

किसी क्वेरी में समान उपश्रेणियाँ।


10
दुर्भाग्य से, कभी-कभी आप सिर्फ इससे बच नहीं सकते हैं - SQL 2000 में "कीवर्ड" के साथ कोई "नहीं था", और UDFs का उपयोग करने के लिए सामान्य सबक्वेरीज़ को एनकैप्सुलेट करने के लिए कुछ समय के लिए पेनल्टी लगती है, उस पर एमएस को दोषी ठहराया जाता है ...
जो Pineda

खैर, उम्मीद है कि वे इन दिनों में से एक को जोड़ने के लिए चारों ओर मिलेंगे।
EvilTeach

SQL 2000 में, आप तालिका चर का उपयोग कर सकते हैं।
पुनरावर्ती

@recursive: आपके पास एक टेबल चर पर अनुक्रमित नहीं हो सकता है, जो अक्सर इसे एक सबक्वेरी की तुलना में धीमा बना देगा। हालाँकि आप कस्टम अनुक्रमित के साथ एक अस्थायी तालिका का उपयोग कर सकते हैं।
रिक

कूल, एसक्यूएल के साथ वर्षों से काम कर रहे हैं, और यह भी नहीं जानते कि कॉमन टेबल एक्सप्रेशन मौजूद हैं (हालांकि मुझे उनकी आवश्यकता होगी)। अब मैं करता हूँ! धन्यवाद!
२३

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

  • पैरामेड - क्या एक क्वेरी में एक से अधिक उद्देश्य हो सकते हैं? शायद लेकिन अगले व्यक्ति जो इसे पढ़ते हैं, वे गहन ध्यान तक नहीं जान पाएंगे। यहां तक ​​कि अगर आप उन्हें अभी जरूरत नहीं है, संभावना है कि आप करेंगे, भले ही यह "बस" डिबग करने के लिए है। मापदंडों के रखरखाव के समय को जोड़ना और चीजों को सूखा रखना। यदि आपके पास एक खंड है जहाँ आपके पास पैरामीटर होना चाहिए।

  • कोई मामला नहीं के लिए मामला -

    SELECT  
    CASE @problem  
      WHEN 'Need to replace column A with this medium to large collection of strings hanging out in my code.'  
        THEN 'Create a table for lookup and add to your from clause.'  
      WHEN 'Scrubbing values in the result set based on some business rules.'  
        THEN 'Fix the data in the database'  
      WHEN 'Formating dates or numbers.'   
        THEN 'Apply formating in the presentation layer.'  
      WHEN 'Createing a cross tab'  
        THEN 'Good, but in reporting you should probably be using cross tab, matrix or pivot templates'   
    ELSE 'You probably found another case for no CASE but now I have to edit my code instead of enriching the data...' END  

वह तीसरा प्यार करता था। मैं पहले से ही इसे स्थानीय रूप से उपयोग कर रहा हूं ...
अल्फा फडॉग

सहारा के लिए धन्यवाद। :)
जसन सालडो

5

दो मुझे सबसे अधिक मिलते हैं, और प्रदर्शन के मामले में एक महत्वपूर्ण लागत हो सकती है:

  • एक सेट आधारित अभिव्यक्ति के बजाय कर्सर का उपयोग करना। मुझे लगता है कि यह अक्सर तब होता है जब प्रोग्रामर प्रक्रियात्मक रूप से सोच रहा होता है।

  • सहसंबद्ध उप-प्रश्नों का उपयोग करना, जब एक व्युत्पन्न तालिका में शामिल होने से काम हो सकता है।


मैं सहमत हूँ अगर तुम मतलब है कि मुझे लगता है कि तुम क्या मतलब है; हालांकि एक सहसंबद्ध उप-क्वेरी व्युत्पन्न तालिका IIRC का एक प्रकार है।
dkretz

1
एक व्युत्पन्न तालिका एक सेट ऑपरेशन है, जबकि बाहरी पंक्ति में प्रत्येक पंक्ति के लिए एक सहसंबद्ध सबक्वेरी चलती है, जिससे यह कम कुशल होता है (10 में से 9 बार)
मिच गेहूं

कुछ साल पहले मुझे अपने आश्चर्य का पता चला कि एसक्यूएल एस किसी भी तरह से सहसंबद्ध प्रश्नों को संभालने के लिए अनुकूलित है: सरल लोगों के लिए आपको एक JOIN का उपयोग करके तार्किक रूप से समान क्वेरी के साथ निष्पादन योजना मिलती है! इसके अलावा, सहसंबंधित प्रश्न जो ओरेकल को अपने घुटनों पर लाते हैं, एसक्यूएल एस पर केवल धीरे-धीरे चलते हैं!
जो पिनेडा

इसलिए मैं इसे हमेशा दोनों तरह से परखता हूं। और I <i> do </> आमतौर पर इसे दोनों तरीकों से आज़माते हैं। व्यवहार में, SQL सर्वर के लिए वैसे भी, मैंने आमतौर पर सहसंबद्ध वर्ग को धीमा होने के लिए पाया है।
dkretz

3
कृपया समझें कि एक सहसंबद्ध उपश्रेणी और एक सम्मिलित IDENTICAL (अधिकांश मामलों में) है। वे अलग-अलग चीजें भी नहीं हैं जो एक-दूसरे के लिए अनुकूलित हैं, लेकिन एक ही ऑपरेशन के अलग-अलग पाठात्मक प्रतिनिधित्व हैं।
इरिक्कलेन

5

अस्थायी तालिकाओं में सामान रखना, विशेष रूप से जो लोग SQL Server से Oracle में स्विच करते हैं, उन्हें अस्थायी तालिकाओं के अति प्रयोग की आदत होती है। बस नेस्टेड स्टेटमेंट का उपयोग करें।


5

डेवलपर्स जो SQL अनुप्रयोगों (दोनों व्यक्तिगत प्रश्नों और बहु-उपयोगकर्ता प्रणालियों) को तेज या धीमा बनाता है, के बारे में अच्छा विचार किए बिना प्रश्न लिखते हैं। इसमें अज्ञानता शामिल है:

  • भौतिक I / O न्यूनकरण रणनीतियाँ, यह देखते हुए कि अधिकांश प्रश्न 'अड़चन I / O नहीं CPU है
  • भौतिक भंडारण पहुंच के विभिन्न प्रकारों का पूर्ण प्रभाव (जैसे बहुत से क्रमिक I / O छोटे यादृच्छिक I / O के बहुत से अधिक तेज़ होंगे, हालाँकि यदि आपका भौतिक संग्रहण SSD है तो कम!)
  • यदि कोई DBMS खराब क्वेरी योजना का निर्माण करता है, तो क्वेरी को कैसे हाथ से तैयार करें
  • खराब डेटाबेस प्रदर्शन का निदान कैसे करें, धीमी क्वेरी "डीबग" कैसे करें, और अपनी पसंद के DBMS के आधार पर एक क्वेरी योजना (या EXPLAIN) कैसे पढ़ें
  • बहु-उपयोगकर्ता अनुप्रयोगों में गतिरोध से बचने और गतिरोध से बचने के लिए लॉकिंग रणनीतियाँ
  • डेटा सेट की प्रोसेसिंग को संभालने के लिए बैचिंग और अन्य ट्रिक्स का महत्व
  • सबसे अच्छा संतुलन स्थान और प्रदर्शन के लिए तालिका और सूचकांक डिजाइन (जैसे सूचकांक को कवर करना, जहां संभव हो सूचकांक को छोटा रखना, डेटा प्रकार को न्यूनतम आकार को कम करना आदि)।

3

SQL को एक गौरवशाली ISAM (अनुक्रमित अनुक्रमिक एक्सेस विधि) पैकेज के रूप में उपयोग करना। विशेष रूप से, एसक्यूएल बयानों को एक एकल में जोड़ने के बजाय शाप देने वाले घोंसले, यद्यपि बड़ा, बयान। यह भी 'ऑप्टिमाइज़र के दुरुपयोग' के रूप में गिना जाता है क्योंकि वास्तव में ऐसा नहीं है कि ऑप्टिमाइज़र बहुत कुछ कर सकता है। इसे अधिकतम अक्षमता के लिए गैर-तैयार बयानों के साथ जोड़ा जा सकता है:

DECLARE c1 CURSOR FOR SELECT Col1, Col2, Col3 FROM Table1

FOREACH c1 INTO a.col1, a.col2, a.col3
    DECLARE c2 CURSOR FOR
        SELECT Item1, Item2, Item3
            FROM Table2
            WHERE Table2.Item1 = a.col2
    FOREACH c2 INTO b.item1, b.item2, b.item3
        ...process data from records a and b...
    END FOREACH
END FOREACH

सही समाधान (लगभग हमेशा) दो चयनित बयानों को एक में मिलाना है:

DECLARE c1 CURSOR FOR
    SELECT Col1, Col2, Col3, Item1, Item2, Item3
        FROM Table1, Table2
        WHERE Table2.Item1 = Table1.Col2
        -- ORDER BY Table1.Col1, Table2.Item1

FOREACH c1 INTO a.col1, a.col2, a.col3, b.item1, b.item2, b.item3
    ...process data from records a and b...
END FOREACH

डबल लूप संस्करण का एकमात्र लाभ यह है कि आप टेबल 1 में मानों के बीच के ब्रेक को आसानी से देख सकते हैं क्योंकि आंतरिक लूप समाप्त होता है। यह कंट्रोल-ब्रेक रिपोर्ट में एक कारक हो सकता है।

इसके अलावा, आवेदन में छँटाई आमतौर पर एक नहीं-नहीं है।


शैली, हालांकि यह वाक्यविन्यास नहीं है, विशेष रूप से मेरे अनुभव में PHP में व्याप्त है।
dkretz

वाक्य-विन्यास वास्तव में IBM Informix-4GL है - लेकिन यह स्पष्ट है कि स्पष्टीकरण के तरीके में बहुत अधिक आवश्यकता नहीं है (मुझे लगता है)। और प्रोग्रामिंग भाषा की परवाह किए बिना, बहुत सारे एसक्यूएल कार्यक्रमों में शैली व्याप्त है।
जोनाथन लेफ्लर

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

और निश्चित रूप से सभी पर कर्सर का उपयोग एक एसक्यूएल एंटीपैटर्न है। वस्तुतः सभी कर्सर को सेट-आधारित संचालन के रूप में फिर से लिखा जा सकता है। कुछ ऐसे नहीं हैं जो केवल DBA के वर्षों के अनुभव के साथ हैं और जो समझते हैं कि कैसे डेटाबेस के इंटर्नल्स लेखन का काम करना चाहिए। किसी भी एप्लिकेशन देव को कभी SQL कर्सर लिखने की आवश्यकता नहीं होनी चाहिए।
HLGEM

3

रिकॉर्ड पतों के लिए एक सरोगेट के रूप में प्राथमिक कुंजी का उपयोग करना और रिकॉर्ड में एम्बेडेड बिंदुओं के लिए एक सरोगेट के रूप में विदेशी कुंजी का उपयोग करना।

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