MySQL, NULL या खाली स्ट्रिंग डालने के लिए बेहतर है?


230

मेरे पास एक वेबसाइट है जिस पर बहुत सारे अलग-अलग क्षेत्र हैं। कुछ फ़ील्ड वैकल्पिक हैं जबकि कुछ अनिवार्य हैं। मेरे DB में मेरे पास एक तालिका है जो इन सभी मूल्यों को रखती है, क्या DB स्तंभ में NULL मान या रिक्त स्ट्रिंग सम्मिलित करने के लिए बेहतर अभ्यास है जहां उपयोगकर्ता ने कोई डेटा नहीं डाला है?

जवाबों:


220

का उपयोग करके NULLआप के बीच भेद कर सकते हैं "कोई डेटा डाल" और "खाली डेटा डाल"।

कुछ और अंतर:

  • एक LENGTHकी NULLहै NULL, एक LENGTHएक खाली स्ट्रिंग की है 0

  • NULLs खाली स्ट्रिंग्स से पहले सॉर्ट किए जाते हैं।

  • COUNT(message)खाली तारों की गिनती करेगा लेकिन NULLएस नहीं

  • आप एक बाउंड वैरिएबल का उपयोग करके एक रिक्त स्ट्रिंग की खोज कर सकते हैं लेकिन ए के लिए नहीं NULL। यह प्रश्न:

    SELECT  *
    FROM    mytable 
    WHERE   mytext = ?

    एक से मेल खाते हैं कभी नहीं होगा NULLमें mytext, आप जो भी मान ग्राहक से गुजरती हैं। NULLS से मेल खाने के लिए , आपको अन्य क्वेरी का उपयोग करना होगा:

    SELECT  *
    FROM    mytable 
    WHERE   mytext IS NULL

3
लेकिन जो आपको लगता है कि तेज है? 0 या NULL या ""
अतुल द्रविड़

8
InnoDB में NULL की जगह कम ली गई है
Timo Huovinen

37
मुझे लगता है कि यह एक ठीक उत्तर है, लेकिन यह प्रश्न के "सर्वोत्तम अभ्यास" तत्व की भी पूरी तरह से उपेक्षा करता है और केवल tangentially प्रासंगिक तथ्यों (पूर्ण क्रम और लंबाई? ये कोई फर्क नहीं पड़ता) पर केंद्रित है। अधिकांश पाठ डेटा इनपुट प्रकारों पर नहीं है "कोई प्रतिक्रिया नहीं" और "खाली प्रतिक्रिया" के बीच कोई अंतर , इसलिए मुझे लगता है कि यह एक महान प्रश्न है जो एक बेहतर उत्तर का हकदार है।
निक

6
जब UNIQUE फ़ील्ड सेट की जाती है तो NULLs भी बढ़िया काम करते हैं। उदाहरण के लिए यदि आपके पास ड्राइविंग लाइसेंस जैसा कोई क्षेत्र है तो व्यक्ति का डीएल नंबर और आदमी को जोड़ने के लिए नहीं है। चूंकि यह एक अनूठा क्षेत्र है, जिसमें कोई डीएल नंबर वाला पहला व्यक्ति नहीं जोड़ा जाएगा, लेकिन अगले के रूप में यह अद्वितीय बाधा की त्रुटि नहीं देगा। तो, NULL बेहतर है।
सैफुर रहमान मोहसिन

1
@Quassnoi आह क्षमा करें ... मेरा मतलब है, ड्राइविंग नंबर लाइसेंस को अद्वितीय के रूप में सेट करने के लिए एक बुरा अभ्यास क्यों है ...?
cedbeu

44

एक बात पर विचार करें, यदि आप कभी भी डेटाबेस स्विच करने की योजना बनाते हैं , तो यह है कि ओरेकल खाली तारों का समर्थन नहीं करता है । वे स्वचालित रूप से NULL में परिवर्तित हो जाते हैं और आप जैसे क्लॉज़ का उपयोग करके उनके लिए क्वेरी नहीं कर सकते WHERE somefield = ''


11
यह आपके लिंक पर भी, मेरे लिए अविश्वसनीय रूप से गड़बड़ लग रहा था, इसलिए मैंने इसे आज़माया। अशक्त क्षेत्र, '' पर सेट, ओर्कल इसकी उपेक्षा करता है। रिपोर्ट लंबाई के बजाय शून्य के रूप में। 0. यह सिर्फ इतना गलत है। इस के आसपास कुछ रास्ता मिल गया है। मुझे लगता है कि मैं इसे एक और सवाल के रूप में पोस्ट करूंगा।
स्टीव बी।

1
Steve B.: इस सवाल को देखें: stackoverflow.com/questions/1171196/…
क्वासनोई

संदर्भ के लिए धन्यवाद, हालांकि मुझे अभी भी तर्क समझ में नहीं आया है। के रूप में प्रकाशित किया गया था stackoverflow.com/questions/1268177/...
स्टीव बी

Quassnoi द्वारा पोस्ट किए गए लिंक से जानकारी को शामिल करने के जवाब को अपडेट करने के लायक हो सकता है
SamuelKDavis

7
Peoplesoft (Oracle DB के साथ) एक रिक्त स्थान को इंगित करने के लिए एकल स्थान का उपयोग करता है। अविश्वसनीय रूप से बेवकूफ। वे 0.00025 का भी उपयोग करते हैं 0 को इंगित करने के लिए 0 क्योंकि अनुमति नहीं है। उस उत्पाद में लवली पसंद किए गए थे।
जेपी डफी

9

एक बात का ध्यान रखें कि NULL आपके कोडपाथ्स को अधिक कठिन बना सकता है। अजगर में उदाहरण के लिए सबसे डेटाबेस एडाप्टर / ORMs नक्शा NULLकरने के लिए None

तो इस तरह की चीजें:

print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow

"हैलो, कोई नहीं डो!" में परिणाम हो सकता है इससे बचने के लिए आपको इस कोड की तरह कुछ चाहिए:

if databaserow.title:
    print "Hello, %(title)s %(firstname) %(lastname)!" % databaserow
else:
    print "Hello, %(firstname) %(lastname)!" % databaserow

जो चीजों को और अधिक जटिल बना सकता है।


25
मेरी राय में आपके डेटाबेस को आपके कोड में "त्रुटियों" को ठीक करने के लिए दुरुपयोग करना या फ्रेमवर्क एक (बहुत) खराब कोडिंग अभ्यास है। जब कोई डेटा नहीं है तो आपको सिर्फ NULL डालना चाहिए और उस का उपयोग करने में सुसंगत होना चाहिए। अन्यथा आपको ऐसे बयानों का उपयोग करना होगा जैसे: if (myString == null || myString = "")। जब कोई ऑब्जेक्ट आपके कोड में सेट या परिभाषित नहीं होता है, तो आप कुछ प्रकार के "प्लेसहोल्डर" के बजाय NULL का उपयोग कर रहे हैं (जो कि मेरी राय में एक रिक्त स्ट्रिंग है)।
गर्टजान

5
अपनी पसंद की भाषा पर बहुत निर्भर करता है। पायथन में "यदि मायस्ट्रिंग नहीं है:" कोई नहीं के लिए परीक्षण और ""। संभवतः मुख्य रूप से एक सांस्कृतिक मुद्दे। जावा दोस्तों "बुरा अभ्यास" गतिशील व्यक्ति की शान है।
अधिकतम

9

NULLMySQL में अपने डेटाबेस में संगति के लिए सम्मिलित करना बेहतर है । विदेशी कुंजियों को संग्रहीत किया जा सकता है NULLलेकिन खाली तारों के रूप में नहीं।

आपके पास बाधाओं में एक खाली स्ट्रिंग के साथ मुद्दे होंगे । विदेशी कुंजी बाधा को संतुष्ट करने के लिए आपको एक अद्वितीय खाली स्ट्रिंग के साथ एक नकली रिकॉर्ड डालना पड़ सकता है । बुरा अभ्यास मुझे लगता है।

यह भी देखें: क्या एक विदेशी कुंजी NULL और / या डुप्लिकेट हो सकती है?


बाधाओं के मुद्दे ने मुझे अतीत में उलझा दिया है, इसीलिए मैंने इस जवाब को "+1" किया है।
HPWD

लेकिन अगर आप NULL का उपयोग करते हैं तो सुनिश्चित करें कि आप कभी भी किसी खाली तार के साथ समाप्त न हों। कई यूआई प्रौद्योगिकियों के साथ करना आसान है।
टंटेबल

5

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

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

ओह, और ध्यान में रखें कि यदि स्तंभ शून्य है, तो रिकॉर्ड उस कॉलम के आधार पर व्यावहारिक रूप से किसी भी क्वेरी को चुनने की संभावना है जो उस कॉलम के आधार पर चयन करता है (जिसमें एक क्लॉज है, SQL शर्तों में), जब तक कि चयन एक शून्य कॉलम के लिए न हो बेशक।


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

1

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

एक अद्वितीय सूचकांक में रंग:
(event_type_id, event_title, दिनांक, स्थान, url)

उदाहरण 1:
(1, 'बीबीक्यू', '2018-07-27', अशक्त, अशक्त)
(1, 'बीबीक्यू', '2018-07-27', अशक्त, अशक्त) // अनुमति और दोहराव।

उदाहरण 2:
(1, 'बीबीक्यू', '2018-07-27', '', '')
(1, 'बीबीक्यू', '2018-07-27', '', '') // इसकी अनुमति नहीं है क्योंकि इसे दोहराया गया है।

यहाँ कुछ कोड हैं:

CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `event_id` int(11) DEFAULT NULL,
  `event_title` varchar(50) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `location` varchar(50) DEFAULT NULL,
  `url` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `event_id` (`event_id`,`event_title`,`date`,`location`,`url`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

अब यह देखने के लिए डालें कि यह डुप्लिकेट की गई पंक्तियों को अनुमति देगा:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-27', NULL, NULL);

अब इसे डालें और जांचें कि इसकी अनुमति नहीं है:

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

INSERT INTO `test` (`id`, `event_id`, `event_title`, `date`, `location`, 
`url`) VALUES (NULL, '1', 'BBQ', '2018-07-28', '', '');

इसलिए, यहां कोई सही या गलत नहीं है। यह आप पर निर्भर करता है कि आपके व्यावसायिक नियमों के साथ क्या काम करता है।

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