Database
 sql >> डेटाबेस >  >> RDS >> Database

NULL के 50 शेड्स – SQL में NULL के विभिन्न अर्थ

टोनी होरे, जिन्हें ज्यादातर NULL संदर्भ के आविष्कारक के रूप में जाना जाता है, अब इसे एक बिलियन-डॉलर की गलती कहते हैं, जो कि अब SQL सहित सभी भाषाओं को "पीड़ित" कर रही है।

टोनी को उद्धृत करना (उनके विकिपीडिया लेख से):

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

यहां दिलचस्प बात यह है कि टोनी उस संदर्भ को लागू करने के लिए ललचा रहा था क्योंकि यह करना आसान था। लेकिन उन्हें इस तरह के संदर्भ की आवश्यकता क्यों थी?

NULL के विभिन्न अर्थ

एक आदर्श दुनिया में, हमें NULL की आवश्यकता नहीं होगी। प्रत्येक व्यक्ति का पहला नाम और अंतिम नाम होता है। प्रत्येक व्यक्ति की एक जन्म तिथि, एक नौकरी आदि होती है। या वे करते हैं?

दुर्भाग्य से, वे ऐसा नहीं करते हैं।

सभी देश प्रथम और अंतिम नामों की अवधारणा का उपयोग नहीं करते हैं।

सभी लोगों के पास नौकरी नहीं है। या कभी-कभी, हम उनका काम नहीं जानते। या हमें परवाह नहीं है।

यह वह जगह है जहाँ NULL अत्यंत उपयोगी है। NULL इन सभी राज्यों को मॉडल कर सकता है जिन्हें हम वास्तव में मॉडल नहीं करना चाहते हैं। NULL हो सकता है:

  • “अपरिभाषित” मान , यानी, वह मान जो अभी तक परिभाषित नहीं है (शायद तकनीकी कारणों से) लेकिन बाद में अच्छी तरह से परिभाषित किया जा सकता है। उस व्यक्ति के बारे में सोचें जिसे हम अन्य तालिकाओं में उपयोग करने के लिए डेटाबेस में जोड़ना चाहते हैं। बाद के किसी चरण में, हम उस व्यक्ति की नौकरी जोड़ देंगे।
  • “अज्ञात” मान , यानी, वह मूल्य जिसे हम नहीं जानते (और कभी नहीं जान सकते)। शायद अब हम इस व्यक्ति या उनके रिश्तेदारों से उनकी जन्मतिथि के बारे में नहीं पूछ सकते - जानकारी हमेशा के लिए खो जाएगी। लेकिन हम अभी भी व्यक्ति को मॉडल बनाना चाहते हैं, इसलिए हम UNKNOWN के अर्थ में NULL का उपयोग करते हैं (जो कि SQL में इसका सही अर्थ है, जैसा कि हम बाद में देखेंगे)।
  • “वैकल्पिक” मान , यानी, वह मान जिसे परिभाषित करने की आवश्यकता नहीं है। ध्यान दें कि "वैकल्पिक" मान बाहरी जॉइन के मामले में भी प्रकट होता है, जब बाहरी जुड़ाव रिश्ते के एक तरफ कोई मूल्य उत्पन्न नहीं करता है। या GROUPING SETS का उपयोग करते समय भी, जहाँ GROUP BY कॉलम के विभिन्न संयोजन संयुक्त होते हैं (या खाली छोड़ दिए जाते हैं)।
  • "हटाया गया" या "बचाया गया" मान , यानी, वह मान जिसे हम निर्दिष्ट नहीं करना चाहते हैं। शायद हम आमतौर पर किसी व्यक्ति की वैवाहिक स्थिति को पंजीकृत करते हैं जैसा कि कुछ न्यायालयों में किया जाता है, लेकिन अन्य में नहीं, जहां इस प्रकार के किसी भी व्यक्तिगत डेटा को पंजीकृत करना कानूनी नहीं है। इसलिए, हम कुछ मामलों में यह मान नहीं जानना चाहते हैं।
  • किसी दिए गए संदर्भ में "विशेष" मान , यानी, वह मान जिसे हम संभावित मानों की श्रेणी में अन्यथा मॉडल नहीं कर सकते। यह अक्सर दिनांक सीमाओं के साथ काम करते समय किया जाता है। मान लें कि किसी व्यक्ति की नौकरी दो तिथियों तक सीमित है, और यदि वह व्यक्ति वर्तमान में उस स्थिति में काम कर रहा है, तो हम यह कहने के लिए NULL का उपयोग करेंगे कि तिथि सीमा के अंत में अवधि असीमित है।
  • "आकस्मिक" शून्य , यानी, NULL मान जो कि केवल NULL है क्योंकि डेवलपर्स ने ध्यान नहीं दिया। एक स्पष्ट नॉट न्यूल बाधा के अभाव में, अधिकांश डेटाबेस कॉलम को अशक्त मान लेते हैं। और एक बार कॉलम खाली होने के बाद, डेवलपर्स केवल "गलती से" अपनी पंक्तियों में NULL मान डाल सकते हैं, जहाँ उनका इरादा भी नहीं था।

जैसा कि हमने ऊपर देखा, ये नल के 50 शेड्स में से कुछ चुनिंदा हैं

निम्न उदाहरण एक ठोस SQL ​​उदाहरण में NULL के विभिन्न अर्थ प्रदर्शित करता है:




CREATE TABLE company (
    id int NOT NULL,
    name text NOT NULL,
    CONSTRAINT company_pk PRIMARY KEY (id)
);
CREATE TABLE job (
    person_id int NOT NULL,
    start_date date NOT NULL,

    -- If end_date IS NULL, the “special value” of an unbounded
    -- interval is encoded
    end_date date NULL,
    description text NOT NULL,

    -- A job doesn’t have to be done at a company. It is “optional”.
    company_id int NULL,
    CONSTRAINT job_pk PRIMARY KEY (person_id,start_date),
    CONSTRAINT job_company FOREIGN KEY (company_id) 
        REFERENCES company (id) 
);
CREATE TABLE person (
    id int  NOT NULL,
    first_name text NOT NULL,

    -- Some people need to be created in the database before we
    -- know their last_names. It is “undefined”
    last_name text NULL,

    -- We may not know the date_of_birth. It is “unknown”
    date_of_birth date NULL,

    -- In some situations, we must not define any marital_status.
    -- It is “deleted”
    marital_status int NULL,
    CONSTRAINT person_pk PRIMARY KEY (id),
    CONSTRAINT job_person FOREIGN KEY (person_id)
        REFERENCES person (id)
); 

लोगों ने हमेशा एक मूल्य की अनुपस्थिति के बारे में तर्क दिया है

जब NULL इतना उपयोगी मूल्य है, तो लोग इसकी आलोचना क्यों करते रहते हैं?

NULL (और अन्य) के लिए इन सभी पिछले उपयोग-मामलों को "द प्रॉब्लम ऑफ मिसिंग इंफॉर्मेशन" (YouTube पर वीडियो देखें) पर C.J. डेट की इस दिलचस्प, हालिया वार्ता में प्रदर्शित किया गया है।

आधुनिक एसक्यूएल बहुत सी भयानक चीजें कर सकता है जो जावा, सी #, पीएचपी जैसी सामान्य प्रयोजन वाली भाषाओं के कुछ डेवलपर्स से अनजान हैं। मैं आपको एक उदाहरण और नीचे दिखाऊंगा।

एक तरह से, सी.जे. डेट टोनी होरे से सहमत हैं कि (एबी) इन सभी विभिन्न प्रकार की "लापता जानकारी" के लिए NULL का उपयोग करना एक बहुत बुरा विकल्प है।

उदाहरण के लिए, इलेक्ट्रॉनिक्स में, समान तकनीकें 1, 0, "संघर्ष", "असाइन्ड", "अज्ञात", "परवाह न करें", "उच्च प्रतिबाधा" जैसी मॉडल चीजों पर लागू होती हैं। हालांकि ध्यान दें, इलेक्ट्रॉनिक्स में कैसे, विभिन्न विशेष मूल्य इन चीजों के लिए उपयोग किया जाता है, एक विशेष NULL मान के बजाय . क्या यह वाकई बेहतर है? "नल", "अपरिभाषित", "0", "NaN", खाली स्ट्रिंग '' जैसे विभिन्न "झूठे" मानों के बीच अंतर के बारे में जावास्क्रिप्ट प्रोग्रामर कैसा महसूस करते हैं? क्या यह वाकई बेहतर है?

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

रिकॉर्ड बताते हैं कि प्राचीन यूनानियों को एक संख्या के रूप में शून्य की स्थिति के बारे में अनिश्चित लग रहा था। उन्होंने खुद से पूछा, "कुछ भी कैसे हो सकता है?", दार्शनिक और मध्ययुगीन काल तक, शून्य और शून्य की प्रकृति और अस्तित्व के बारे में धार्मिक तर्क।

जैसा कि हम देख सकते हैं, "धार्मिक तर्क" स्पष्ट रूप से कंप्यूटर विज्ञान और सॉफ्टवेयर तक फैले हुए हैं, जहां हम अभी भी निश्चित रूप से नहीं जानते कि मूल्य की अनुपस्थिति के साथ क्या करना है।

वास्तविकता पर वापस जाएं:SQL में NULL

जबकि लोग (शिक्षाविदों सहित) अभी भी इस तथ्य पर सहमत नहीं हैं कि क्या हमें "अपरिभाषित", "अज्ञात", "वैकल्पिक", "हटाए गए", "विशेष" के लिए किसी एन्कोडिंग की आवश्यकता है, आइए हम वास्तविकता और बुरे भागों के बारे में वापस आते हैं SQL का NULL.

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

अगर हम अपने मॉडल पर वापस जाते हैं:





उदाहरण के लिए, यदि हम सहज रूप से उन सभी लोगों को ढूंढना चाहते हैं, जो विवाहित होने के रूप में पंजीकृत नहीं हैं, तो हम निम्नलिखित कथन लिखना चाहेंगे:

SELECT * FROM person WHERE marital_status != 'married'

दुर्भाग्य से, तीन-मान वाले लॉजिक और SQL के NULL के कारण, उपरोक्त क्वेरी उन मानों को वापस नहीं करेगी जिनमें कोई स्पष्ट वैवाहिक_स्थिति नहीं है। इसलिए, हमें एक अतिरिक्त, स्पष्ट विधेय लिखने की आवश्यकता होगी:

SELECT * FROM person 
WHERE marital_status != 'married'
OR marital_status IS NULL

या, हम मान की तुलना करने से पहले कुछ NOT NULL मान के साथ जबरदस्ती करते हैं

SELECT * FROM person
WHERE COALESCE(marital_status, 'null') != 'married'

तीन महत्वपूर्ण तर्क कठिन हैं। और SQL में NULL के साथ यह एकमात्र समस्या नहीं है। यहाँ NULL का उपयोग करने के अधिक नुकसान हैं:

  • केवल एक NULL है, जब हम वास्तव में कई अलग-अलग "अनुपस्थित" या "विशेष" मानों को एन्कोड करना चाहते थे। उपयोगी विशेष मूल्यों की श्रेणी अत्यधिक डोमेन और उपयोग किए जाने वाले डेटा प्रकारों पर निर्भर करती है। फिर भी, एक अशक्त स्तंभ के अर्थ की सही व्याख्या करने के लिए डोमेन ज्ञान की हमेशा आवश्यकता होती है, और गलत परिणामों को वापस आने से रोकने के लिए प्रश्नों को सावधानीपूर्वक डिज़ाइन किया जाना चाहिए, जैसा कि हमने ऊपर देखा।
  • फिर से, तीन-मूल्यवान तर्क को ठीक करना बहुत कठिन है। जबकि ऊपर दिया गया उदाहरण अभी भी सरल है, आपको क्या लगता है कि निम्नलिखित प्रश्न क्या प्राप्त करेंगे?
    SELECT * FROM person 
    WHERE marital_status NOT IN ('married', NULL)
    

    बिल्कुल सही। यह कुछ भी नहीं देगा, जैसा कि इस लेख में यहां बताया गया है। संक्षेप में, उपरोक्त क्वेरी नीचे दी गई क्वेरी के समान है:

    SELECT * FROM person 
    WHERE marital_status != 'married'
    AND marital_status != NULL -- This is always NULL / UNKNOWN
    
  • Oracle डेटाबेस NULL और खाली स्ट्रिंग '' को एक ही चीज़ मानता है। यह बहुत मुश्किल है क्योंकि आप तुरंत ध्यान नहीं देंगे कि निम्नलिखित क्वेरी हमेशा एक खाली परिणाम क्यों देती है:

    SELECT * FROM person 
    WHERE marital_status NOT IN ('married', '')
    

  • Oracle (फिर से) NULL मान को अनुक्रमणिका में नहीं डालता है। यह कई खराब प्रदर्शन समस्याओं का स्रोत है, उदाहरण के लिए, जब आप NOT IN विधेय में एक अशक्त स्तंभ का उपयोग कर रहे हैं जैसे:

    SELECT * FROM person 
    WHERE marital_status NOT IN (
      SELECT some_nullable_column
      FROM some_table
    )
    

    Oracle के साथ, उपरोक्त एंटी-जॉइन के परिणामस्वरूप एक पूर्ण तालिका स्कैन होगा, भले ही आपके पास some_nullable_column पर कोई अनुक्रमणिका हो। तीन-मूल्यवान तर्क के कारण और क्योंकि Oracle NULLs को अनुक्रमणिका में नहीं रखता है, इंजन को तालिका को हिट करने और प्रत्येक मान की जाँच करने की आवश्यकता होगी, यह सुनिश्चित करने के लिए कि सेट में कम से कम एक NULL मान नहीं है, जो बना देगा संपूर्ण विधेय UNKNOWN.

निष्कर्ष

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

यदि आप अपने डेटाबेस डिज़ाइन के साथ सुरक्षित पक्ष पर रहना चाहते हैं, तो हर कीमत पर एनयूएलएल से बचें, जब तक कि आपको न्यूल का उपयोग करके एन्कोड करने के लिए उन विशेष मानों में से एक की आवश्यकता न हो। याद रखें, ये मान हैं:"अपरिभाषित", "अज्ञात", "वैकल्पिक", "हटाया गया", और "विशेष", और बहुत कुछ:न्यूल के 50 शेड्स . यदि आप ऐसी स्थिति में नहीं हैं, तो हमेशा अपने डेटाबेस के प्रत्येक कॉलम में NOT NULL बाधा जोड़ने के लिए डिफ़ॉल्ट करें। आपका डिज़ाइन बहुत साफ़ होगा, और आपका प्रदर्शन बहुत बेहतर होगा।

यदि डीडीएल में केवल NOT NULL डिफ़ॉल्ट थे, और NULLABLE वह कीवर्ड है जिसे स्पष्ट रूप से सेट करने की आवश्यकता है…

NULL के साथ आपके अनुभव और अनुभव क्या हैं? आपकी राय में एक बेहतर SQL कैसे काम करेगा?

लुकास एडर स्विट्जरलैंड के ज्यूरिख में स्थित डेटा गीकरी जीएमबीएच के संस्थापक और सीईओ हैं। डेटा गीकरी 2013 से जावा और एसक्यूएल के आसपास डेटाबेस उत्पादों और सेवाओं की बिक्री कर रहा है।

2006 में EPFL में अपने मास्टर की पढ़ाई के बाद से, वह Java और SQL की बातचीत से मोहित हो गया है। इस अनुभव का अधिकांश हिस्सा उन्होंने स्विस ई-बैंकिंग क्षेत्र में विभिन्न रूपों (जेडीबीसी, हाइबरनेट, ज्यादातर ओरेकल के साथ) के माध्यम से प्राप्त किया है। उन्हें इस ज्ञान को विभिन्न सम्मेलनों, जेयूजी, इन-हाउस प्रस्तुतियों और अपने कंपनी ब्लॉग में साझा करने में प्रसन्नता हो रही है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक सामग्री दस्तावेज़ को सेल्सफोर्स कस्टम ऑब्जेक्ट में संलग्न करना

  2. नेस्टेड लूप्स जॉइन और परफॉर्मेंस स्पूल

  3. SQL संदर्भ तालिका:मूल प्रश्न कैसे बनाएं और लिखें

  4. कौवा का पैर संकेतन

  5. एसएसएएस के लिए विस्तारित कार्यक्रम