SQL में VARCHAR पर CHAR के चयन के लिए उपयोग के मामले क्या हैं?


270

मुझे लगता है कि CHAR की सिफारिश की जाती है यदि मेरे सभी मान निश्चित-चौड़ाई वाले हैं। लेकिन तो क्या? सिर्फ सुरक्षित रहने के लिए सभी पाठ क्षेत्रों के लिए VARCHAR को ही क्यों चुना।

जवाबों:


386

आम तौर पर CHAR उठाओ अगर सभी पंक्तियों की लंबाई समान होगी । जब लंबाई काफी भिन्न होती है , तो VARCHAR चुनें । CHAR थोड़ा तेज़ भी हो सकता है क्योंकि सभी पंक्तियाँ एक ही लंबाई की होती हैं।

यह DB कार्यान्वयन द्वारा भिन्न होता है, लेकिन आमतौर पर VARCHAR वास्तविक डेटा के अलावा एक या दो अधिक बाइट्स स्टोरेज (लंबाई या समाप्ति के लिए) का उपयोग करता है। इसलिए (यह मानते हुए कि आप एक बाइट कैरेक्टर सेट का उपयोग कर रहे हैं) "फूबर" शब्द को संग्रहीत करता है

  • CHAR (6) = 6 बाइट्स (ओवरहेड नहीं)
  • VARCHAR (10) = 8 बाइट्स (ओवरहेड के 2 बाइट्स)
  • CHAR (10) = 10 बाइट्स (ओवरहेड के 4 बाइट्स)

लब्बोलुआब यह है कि CHAR अपेक्षाकृत समान लंबाई (दो वर्णों की लंबाई में अंतर) के डेटा के लिए अधिक तेज़ और अधिक स्थान कुशल हो सकता है ।

नोट : Microsoft SQL में VARCHAR के लिए 2 बाइट्स ओवरहेड हैं। यह DB से DB तक भिन्न हो सकता है, लेकिन आम तौर पर एक VCHCHAR पर लंबाई या EOL को इंगित करने के लिए ओवरहेड की कम से कम 1 बाइट की आवश्यकता होती है।

जैसा कि गेवन द्वारा टिप्पणियों में कहा गया था, यदि आप एक मल्टी-बाइट का उपयोग कर रहे हैं, तो वेरिएबल लेंथ कैरेक्टर UTF8 की तरह सेट होता है, तब CHAR वर्णों की संख्या को संग्रहीत करने के लिए आवश्यक बाइट्स की अधिकतम संख्या को संग्रहीत करता है। इसलिए अगर किसी कैरेक्टर को स्टोर करने के लिए UTF8 को सबसे ज्यादा 3 बाइट्स की जरूरत होती है, तो CHAR (6) 18 बाइट्स पर फिक्स किया जाएगा, भले ही केवल लैटिन 1 कैरेक्टर्स को स्टोर कर रहे हों। तो इस मामले में VARCHAR एक बेहतर विकल्प बन जाता है।


20
एक और कारण पृष्ठ विभाजन और विखंडन है। मेरे पास IDEN PK के साथ एक तालिका थी जो कि varchar कॉलम पर पृष्ठ विभाजन के कारण 99% खंडित हो गई थी। एक बहुत सक्रिय तालिका और अनुप्रयोग की प्रकृति से एक नई पंक्ति खाली पंक्ति बनाई जाएगी और फिर आबादी होगी। चार ने विखंडन की समस्या को ठीक किया।
पेपराराज़ो

12
@ जिम मैककेथ - ये गणना केवल तभी सही हैं जब आप लैटिन 1 चारसेट का उपयोग कर रहे हैं। चूंकि अधिकांश लोग इन दिनों utf8 का उपयोग कर रहे हैं, इसलिए आपके CHAR कॉलम औसतन VARCHAR के रूप में 3x स्थान का उपयोग करने जा रहे हैं जो कि आधार बहुभाषी विमान में ज्यादातर वर्णों को संग्रहीत कर रहा है।
गैविन टोवी

11
@JimMcKeeth हाँ, यह बिल्कुल सही है। चूंकि CHAR निश्चित लंबाई है, इसलिए इसे अधिकतम संभव स्थान पर तय किया जाना चाहिए जिसका उपयोग किया जा सकता है। UTF8 में यह प्रति वर्ण 3 बाइट्स है। Varchar के लिए, जरूरत के अनुसार प्रति वर्ण 1-3 बाइट्स का उपयोग करना मुफ्त है। यह MySQL मैनुअल में है: dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html
Gavin Towey

3
स्ट्रिंग FooBar और varchar (100) बनाम चार (100) में क्या अंतर है? मैं सोच रहा हूँ कि अंतर को बेहतर प्रदर्शित करता है, हाँ? नहीं?
नेनोटलेप

4
@GavinTowey SQLSERVER अपने NCHAR और NVARCHAR डेटाटिप्स के लिए UCS-2 का उपयोग करता है। यह हमेशा प्रति वर्ण दो बाइट्स है।
0010

69

यदि आप मेरे साथ काम कर रहे हैं और आप ओरेकल के साथ काम कर रहे हैं, तो मैं शायद आपको varcharलगभग हर परिस्थिति में उपयोग करूँगा । अनुमान है कि charकम प्रसंस्करण शक्ति का उपयोग करता varcharहै सच हो सकता है ... अभी के लिए ... लेकिन डेटाबेस इंजन समय के साथ बेहतर हो जाते हैं और इस तरह के सामान्य नियम से भविष्य "मिथक" बनता है।

एक और बात: मैंने कभी कोई प्रदर्शन समस्या नहीं देखी क्योंकि किसी ने साथ जाने का फैसला किया varchar। आप अपने समय को बेहतर कोड लिखने (डेटाबेस के लिए कम कॉल) और कुशल एसक्यूएल (कैसे अनुक्रमणिका काम करते हैं, कैसे ऑप्टिमाइज़र निर्णय करता है, क्यों आम तौर पर existsतेजी से inहोता है ...) का बेहतर उपयोग करेंगे।

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


20
मैं आपके पहले पैराग्राफ से कुछ हद तक असहमत हूं, क्योंकि हो सकता है कि चर एक संकेत प्रदान करे जो कि आशावादी, यहां तक ​​कि भविष्य के लोगों के लिए उपयोगी हो सकता है, और यह कॉलम के इरादे को संप्रेषित करने में मदद कर सकता है। लेकिन आपके तीसरे पैराग्राफ के लिए +1। मुझे सभी अतिरिक्त स्थानों से नफरत है। एक फ़ील्ड को बस स्टोर करना चाहिए जो मैंने इसमें डाला [सभी] खोज के बिना पैडिंग। मूल रूप से, मैं सिर्फ चार का उपयोग करता हूं यदि सभी डेटा बिल्कुल समान लंबाई के हों, कोई अधिक और कम नहीं, अभी और हमेशा के लिए। यह बहुत दुर्लभ है, ज़ाहिर है, और आमतौर पर एक चार (1) है।
जेफरी एल व्हाइटलेज

char विश्लेषकों और डेवलपर्स को एक संकेत भी प्रदान करता है ... यह बात वर्णों की x संख्या है .... यदि वे इसे किसी अन्य प्रारूप में क्रमबद्ध करने के बारे में सोच रहे हैं, तो यह उपयोगी हो सकता है। (मुझे mssql में एक md5 चेकसम को स्टोर करने के लिए मजबूर किया गया था जिसमें एक uuid प्रकार नहीं था ... और मुझे कभी भी कुछ भी नहीं चाहिए <32 बाइट्स ... स्तंभ पर एक बाधा भी डाल दी)।
जोफ्रोमक्ट

31

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


या देश कोड - एक 2 या 3 चरित्र देश कोड संक्षिप्त नाम का उपयोग करने के बीच अंतर करने में मदद कर सकता है
डैन फील्ड

यदि यह वास्तव में एक निश्चित लंबाई है, तो इसे लागू करने में एक बाधा होनी चाहिए। यद्यपि यदि आप उपयोग करते हैं CHAR, तो आपको यह सुनिश्चित करना होगा कि आपकी बाधा छूट पैडिंग है।
jpmc26

18

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


4
यकीन नहीं है कि यह एक महान जवाब है, क्योंकि एक ENUM आमतौर पर बहुत अधिक समझ में आता है, हालांकि मुझे यकीन नहीं है कि उस प्रकार का व्यापक रूप से समर्थन कैसे किया जाता है (MySQL के बाहर)।
बॉबी जैक

मुझे लगता है कि राज्यों का सेट जरूरी अपरिवर्तनीय नहीं है, इसलिए चार (2) एक एनम की तुलना में बहुत अधिक उपयुक्त लगता है।
Kearns

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

4
खराब उदाहरण, ENUM उस मामले के लिए सबसे अच्छा है। बेहतर उदाहरण एक 3 पत्र IATA हवाई अड्डा कोड होगा
एंड्रयू जी। जॉनसन

5
@ और, नहीं सभी db का समर्थन ENUM डेटा प्रकार। MSSQLServer, उदाहरण के लिए, नहीं करता है। इसके अलावा, एक ENUM, एक इंट के रूप में संग्रहीत, 4 बाइट्स लेता है। CHAR (1) 1 बाइट लेता है, और NCHAR (1) 2 बाइट लेता है।
जरेट मेयर

17

क्या एनसीएचआर या चार बेहतर प्रदर्शन करते हैं कि उनके संस्करण विकल्प?

बड़ा सवाल है। कुछ स्थितियों में सरल उत्तर हाँ है। आइए देखें कि क्या यह समझाया जा सकता है।

स्पष्ट रूप से हम सभी जानते हैं कि अगर मैं varchar (255) के कॉलम के साथ एक तालिका बनाता हूं (चलो इस कॉलम को myColumn कहते हैं) और एक लाख पंक्तियाँ डालें, लेकिन प्रत्येक पंक्ति के लिए myColumn में केवल कुछ वर्ण डालें, तालिका बहुत छोटी होगी (कुल मिलाकर) स्टोरेज इंजन द्वारा आवश्यक डेटा पेजों की संख्या) की तुलना में अगर मैंने चारकोल (255) के रूप में myColumn बनाया है। कभी भी मैं उस मेज पर एक ऑपरेशन (डीएमएल) करता हूं और पंक्तियों का एक बहुत अनुरोध करता हूं, यह तेजी से तब होगा जब myColumn varchar है क्योंकि मुझे अंत में उन सभी "अतिरिक्त" रिक्त स्थान के आसपास नहीं जाना है । ले जाएँ, जैसे कि जब SQL सर्वर आंतरिक प्रकार करता है जैसे कि एक अलग या यूनियन ऑपरेशन के दौरान, या यदि यह इसके प्लान के दौरान मर्ज चुनता है, आदि।

लेकिन वर्चर का उपयोग करने में कुछ ओवरहेड है। SQL सर्वर को प्रत्येक पंक्ति में दो बाइट इंडिकेटर (ओवरहेड) का उपयोग करना पड़ता है, यह जानने के लिए कि उस विशेष पंक्ति के myColumn में कितने बाइट हैं। यह अतिरिक्त 2 बाइट्स नहीं है जो समस्या प्रस्तुत करता है, यह हर पंक्ति में myColumn में डेटा की लंबाई को "डिकोड" करने वाला है।

मेरे अनुभवों में यह उन कॉलमों पर varchar के बजाय char का उपयोग करने के लिए सबसे अधिक समझ में आता है, जिन्हें प्रश्नों में शामिल किया जाएगा। उदाहरण के लिए एक टेबल की प्राथमिक कुंजी, या कुछ अन्य कॉलम जिन्हें अनुक्रमित किया जाएगा। एक जनसांख्यिकीय टेबल पर CustomerNumber, या एक डिकोड टेबल पर CodeID, या एक ऑर्डर टेबल पर शायद OrderNumber। चार का उपयोग करके, क्वेरी इंजन अधिक तेज़ी से जुड़ने का प्रदर्शन कर सकता है क्योंकि यह सीधे सूचक अंकगणित (नियतात्मक रूप से) कर सकता है बजाय इसे स्थानांतरित करने के बाइट्स की चर राशि को इंगित करता है क्योंकि यह पृष्ठ पढ़ता है। मुझे पता है कि मैंने आपको उस आखिरी वाक्य में खो दिया होगा। SQL सर्वर में शामिल होने के बारे में "भविष्यवाणी" के विचार पर आधारित हैं। एक विधेय एक शर्त है। उदाहरण के लिए myColumn = 1, या ऑर्डरनंबर <500।

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

अब ध्यान रखें कि इसे आसानी से खराब तरीके से लागू किया जा सकता है। मैंने ऑनलाइन सिस्टम में प्राथमिक कुंजी फ़ील्ड के लिए उपयोग किया गया char देखा है। चौड़ाई को छोटा यानी चार (15) या कुछ उचित रखना चाहिए। और यह ऑनलाइन सिस्टम में सबसे अच्छा काम करता है क्योंकि आप आमतौर पर केवल छोटी संख्या में पंक्तियों को पुनः प्राप्त या उभारते हैं, इसलिए आपके द्वारा परिणाम सेट में प्राप्त होने वाले रिक्त स्थान को "rrrim" करना एक तुच्छ कार्य है, जिसमें लाखों लोगों के शामिल होने का विरोध किया जाता है एक टेबल से दूसरी टेबल पर पंक्तियों की पंक्तियाँ।

एक और कारण CHAR ऑनलाइन सिस्टम पर varchar पर समझ में आता है, यह पेज विभाजन को कम करता है। चार का उपयोग करके, आप अनिवार्य रूप से उस स्थान को "जला रहे हैं" (और बर्बाद कर रहे हैं) यदि उपयोगकर्ता बाद में आता है और उस कॉलम में अधिक डेटा डालता है तो SQL उसके लिए पहले ही स्थान आवंटित कर देता है और उसमें चला जाता है।

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

तो वे 3 तरीके हैं जो एक ऑनलाइन (ओएलटीपी) प्रणाली है जो चरचर से अधिक लाभ उठा सकती है। मैं शायद ही कभी किसी गोदाम / विश्लेषण / OLAP परिदृश्य में चार का उपयोग करता हूं क्योंकि आमतौर पर आपके पास SO डेटा होता है जो उन सभी चार स्तंभों को बहुत सारे बर्बाद स्थान तक जोड़ सकते हैं।

ध्यान रखें कि चार आपके डेटाबेस को बहुत बड़ा बना सकते हैं लेकिन अधिकांश बैकअप टूल में डेटा कम्प्रेशन होता है जिससे आपके बैकअप उसी आकार के हो जाते हैं जैसे आपने varchar का उपयोग किया था। उदाहरण के लिए LiteSpeed ​​या RedGate SQL बैकअप।

एक अन्य उपयोग एक निश्चित चौड़ाई की फ़ाइल में डेटा निर्यात करने के लिए बनाए गए विचारों में है। मान लीजिए कि मुझे मेनफ्रेम द्वारा पढ़ने के लिए कुछ डेटा को एक फ्लैट फ़ाइल में निर्यात करना है। यह निश्चित चौड़ाई (सीमांकित नहीं है) है। मैं अपने "स्टेजिंग" टेबल में डेटा को varchar के रूप में संग्रहीत करना पसंद करता हूं (इस प्रकार मेरे डेटाबेस पर कम जगह का उपभोग करता है) और फिर उस कॉलम के लिए तय चौड़ाई की चौड़ाई के अनुरूप लंबाई के साथ सब कुछ कास्ट करने के लिए एक दृश्य का उपयोग करें। । उदाहरण के लिए:

create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )

insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)

create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))

SELECT * from vwStagingTable

यह शांत है क्योंकि आंतरिक रूप से मेरा डेटा कम जगह लेता है क्योंकि यह varchar का उपयोग कर रहा है। लेकिन जब मैं डीटीएस या एसएसआईएस या यहां तक ​​कि एसएसएमएस से नोटपैड तक सिर्फ एक कट और पेस्ट का उपयोग करता हूं, तो मैं दृश्य का उपयोग कर सकता हूं और सही संख्या में अनुगामी रिक्त स्थान प्राप्त कर सकता हूं। DTS में हमारे पास एक फीचर होता था जिसे धिक्कार है, मुझे लगता है कि मुझे लगता है कि इसे "कॉलम का सुझाव दें" या कुछ और था। SSIS में आप अब ऐसा नहीं कर सकते, आपको फ्लैट फ़ाइल कनेक्शन प्रबंधक को स्पष्ट रूप से परिभाषित करना होगा। लेकिन जब से आपके पास अपना दृश्य सेटअप है, SSIS प्रत्येक कॉलम की चौड़ाई को जान सकता है और यह आपके डेटा प्रवाह कार्यों का निर्माण करते समय बहुत कुछ बचा सकता है।

तो नीचे पंक्ति ... varchar का उपयोग करें। चार का उपयोग करने के लिए बहुत कम कारण हैं और यह केवल प्रदर्शन कारणों के लिए है। यदि आपके पास लाखों पंक्तियों की hundrends के साथ एक प्रणाली है, तो आप एक ध्यान देने योग्य अंतर देखेंगे यदि विधेय नियतांक (char) हैं, लेकिन अधिकांश प्रणालियों के लिए char का उपयोग करना केवल स्थान बर्बाद कर रहा है।

उम्मीद है की वो मदद करदे। जेफ


आप कह रहे हैं कि फिक्स्ड चैट न केवल संग्रहीत होने पर अधिक स्थान लेता है, बल्कि जब आप कहते हैं तो परिवहन या "स्थानांतरित" किया जाता है? उदाहरण के लिए DB सर्वर से मेरे ग्राहक के लिए? हम उन अशक्त बाइट्स को कब खोते हैं?
लाल मटर

9

प्रदर्शन लाभ हैं, लेकिन यहाँ एक है जिसका उल्लेख नहीं किया गया है: पंक्ति प्रवासन। चार के साथ, आप अग्रिम में पूरे स्थान को आरक्षित करते हैं। मान लीजिए कि आपके पास चार (1000) है, और आप 10 वर्णों को संग्रहीत करते हैं, तो आप सभी 1000 चार्टरों का उपयोग करेंगे। एक varchar2 (1000) में, आप केवल 10 वर्णों का उपयोग करेंगे। समस्या तब आती है जब आप डेटा को संशोधित करते हैं। मान लें कि आप कॉलम को अपडेट करते हैं जिसमें 900 अक्षर हैं। यह संभव है कि वर्कर का विस्तार करने का स्थान वर्तमान ब्लॉक में उपलब्ध न हो। उस स्थिति में, DB इंजन को पंक्ति को दूसरे ब्लॉक में स्थानांतरित करना होगा, और नए ब्लॉक में मूल ब्लॉक में एक पॉइंटर बनाना होगा। इस डेटा को पढ़ने के लिए, DB इंजन को अब 2 ब्लॉक पढ़ना होगा।
कोई भी समान रूप से यह नहीं कह सकता है कि वरचर या चार बेहतर हैं। ट्रेडऑफ़ के लिए एक स्थान है, और इस बात पर विचार करना कि क्या डेटा अपडेट किया जाएगा, खासकर अगर एक अच्छा मौका है कि यह बढ़ेगा।


मुझे लगता है कि आपके पोस्ट में एक टाइपो है - क्या varchar2 (1000) CHAR (1000) नहीं होना चाहिए?
मैट रोजिश

8

प्रारंभिक प्रदर्शन अनुकूलन और नियम का सबसे अच्छा अभ्यास प्रकार का उपयोग करने के बीच अंतर है। यदि आप नई तालिकाएँ बना रहे हैं, जहाँ आपके पास हमेशा एक निश्चित लंबाई क्षेत्र होगा, तो यह CHAR का उपयोग करने के लिए समझ में आता है, आपको उस स्थिति में इसका उपयोग करना चाहिए। यह प्रारंभिक अनुकूलन नहीं है, बल्कि अंगूठे के नियम (या सर्वोत्तम अभ्यास) को लागू करना है।

अर्थात - यदि आपके पास 2 अक्षर का राज्य क्षेत्र है, तो CHAR (2) का उपयोग करें। यदि आपके पास वास्तविक राज्य नामों के साथ कोई फ़ील्ड है, तो VARCHAR का उपयोग करें।


8

मैं तब तक varchar का चयन करूंगा जब तक कि कॉलम में अमेरिकी राज्य कोड जैसे निश्चित मूल्य नहीं होंगे - जो हमेशा 2 चार्ट लंबा होता है और मान्य US राज्यों कोड की सूची अक्सर नहीं बदलती है :)।

हर दूसरे मामले में, यहां तक ​​कि हैशेड पासवर्ड (जो निश्चित लंबाई है) को संग्रहीत करने की तरह, मैं varchar को चुनूंगा।

क्यों - चार प्रकार का कॉलम हमेशा रिक्त स्थान के साथ पूरा होता है, जो कॉलम my_column को चार (5) के रूप में परिभाषित करता है, जिसमें मूल्य 'एबीसी' तुलना के अंदर होता है:

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

असत्य।

यह सुविधा विकास के दौरान कई परेशान कर सकती है और परीक्षण को कठिन बना देती है।


1
कम से कम MSSQL सर्वर में, 'abc' = 'abc'। मुझे कभी भी यह पता नहीं चला है कि मुझे वह सुविधा पसंद है या नहीं। ....
मार्क ब्रैकेट


6

यदि VARCHAR की तुलना में CHAR कम संग्रहण स्थान लेता है, तो उस क्षेत्र में आपके सभी डेटा मान समान हैं। अब शायद 2009 में एक 800GB डेटाबेस सभी इरादों और प्रयोजनों के लिए 810GB के समान है यदि आपने VARCHARs को CHAR में बदल दिया है, लेकिन छोटे तारों (1 या 2 वर्णों) के लिए, CHAR अभी भी एक उद्योग है "सबसे अच्छा अभ्यास" मैं कहूंगा।

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

लेकिन इसका एक दिलचस्प तर्क है, और समय के साथ डेटाबेस में सुधार के रूप में, यह तर्क दिया जा सकता है CHAR बनाम VARCHAR कम प्रासंगिक हो जाता है।


4

मैं जिम मैककेथ की टिप्पणी से खड़ा हूं।

इसके अलावा, यदि आपकी तालिका में केवल CHAR स्तंभ हैं, तो अनुक्रमण और पूर्ण तालिका स्कैन तेज़ हैं। मूल रूप से ऑप्टिमाइज़र यह अनुमान लगाने में सक्षम होगा कि प्रत्येक रिकॉर्ड कितना बड़ा है यदि इसमें केवल CHAR कॉलम हैं, जबकि इसे प्रत्येक VARCHAR कॉलम के आकार के मूल्य की जांच करने की आवश्यकता है।

इसके अलावा अगर आप VARCHAR कॉलम को उसकी पिछली सामग्री से बड़े आकार में अपडेट करते हैं, तो आप डेटाबेस को इसके अनुक्रमित को फिर से बनाने के लिए मजबूर कर सकते हैं (क्योंकि आपने डेटाबेस को डिस्क पर रिकॉर्ड करने के लिए भौतिक रूप से स्थानांतरित करने के लिए मजबूर किया है)। जबकि CHAR कॉलम के साथ ऐसा कभी नहीं होगा।

जब तक कि आपकी तालिका बहुत बड़ी न हो, तब तक आप शायद प्रदर्शन हिट की परवाह नहीं करेंगे।

याद कीजिए जिक्रास्त के समझदार शब्द। प्रारंभिक प्रदर्शन अनुकूलन सभी बुराई की जड़ है।


4
आपकी टिप्पणी में कुछ अटकलें हैं। मैंने समय और समय की धारणाओं को फिर से देखा है जैसे कि इनका परीक्षण किया जाता है और सटीक विपरीत सच हो जाता है। समस्या यह है कि कई इंजीनियर इस तरह से सुसमाचार के रूप में जानकारी लेंगे। कृपया लोग, परीक्षण के मामले बनाएं जो आपकी वास्तविक स्थितियों को दर्शाते हैं।
एथन पोस्ट

ईथन पूरी तरह से सही है। यह इस तरह लागू होता है कि आप वास्तविक (उत्पाद, संस्करण) के संदर्भ के बिना इसका उपयोग कर रहे हैं, यह पूरी तरह से बेकार है।
डेविड श्मिट

जब आप किसी CHARकॉलम को अपडेट करते हैं , तो इंडेक्स को भी अपडेट किया जाना चाहिए। उस संबंध में VARCHAR या CHAR कॉलम को अपडेट करने में कोई अंतर नहीं है। अपडेट FOOकरने के बारे में सोचें BAR
a_horse_with_no_name

4

कई लोगों ने बताया है कि यदि आप जानते हैं कि CHAR के उपयोग से मूल्य की सही लंबाई के कुछ लाभ हैं। लेकिन अमेरिकी राज्यों को CHAR (2) के रूप में संग्रहीत करते हुए आज बहुत अच्छा है, जब आपको बिक्री से यह संदेश मिलता है कि 'हमने अभी ऑस्ट्रेलिया को अपनी पहली बिक्री की है', आप दर्द की दुनिया में हैं। मैं हमेशा ओवरस्टीट भेजता हूं कि मुझे लगता है कि भविष्य की घटनाओं के लिए कवर करने के लिए फ़ील्ड्स को 'सटीक' अनुमान बनाने के बजाय फ़ील्ड्स की आवश्यकता होगी। VARCHAR मुझे इस क्षेत्र में और अधिक लचीलापन देगा।


3

मुझे लगता है कि आपके मामले में वरचेर को नहीं लेने का कोई कारण नहीं है। यह आपको लचीलापन देता है और जैसा कि कई उत्तरदाताओं द्वारा उल्लेख किया गया है, प्रदर्शन अब ऐसा है कि बहुत विशिष्ट परिस्थितियों को छोड़कर हमर मॉर्टल्स (जैसा कि Google DBA के विपरीत है) अंतर को नोटिस नहीं करेंगे।

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

मैं हमेशा VarChar का उपयोग करता हूं और आमतौर पर मैं इसे बहुत बड़ा बनाता हूं जितना मुझे सख्त जरूरत है। उदाहरण के लिए। Firstname के लिए 50, जैसा कि आप कहते हैं कि सिर्फ सुरक्षित होने के लिए क्यों नहीं।


3

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

तो यहां कुछ मुद्दे दिए गए हैं:

हर क्षेत्र को गद्देदार किया जाएगा, ताकि आप हमेशा के लिए कोड के साथ समाप्त हो जाएं जिसमें आरटीआरआईएमएस हो। यह लंबे क्षेत्रों के लिए एक विशाल डिस्क स्थान अपशिष्ट भी है।

अब मान लेते हैं कि आपके पास केवल एक वर्ण के चार क्षेत्र का सर्वोत्कृष्ट उदाहरण है, लेकिन क्षेत्र वैकल्पिक है। यदि कोई खाली स्ट्रिंग उस क्षेत्र में जाता है तो वह एक स्थान बन जाता है। इसलिए जब कोई अन्य एप्लिकेशन / प्रक्रिया इस पर सवाल उठाती है, तो उन्हें एक ही स्थान मिलता है, अगर वे rtrim का उपयोग नहीं करते हैं। हमारे पास xml दस्तावेज़, फ़ाइलें और अन्य कार्यक्रम हैं, केवल एक स्थान प्रदर्शित करें, वैकल्पिक फ़ील्ड में और चीजों को तोड़ दें।

तो अब आपको यह सुनिश्चित करना है कि आप रिक्त फ़ील्ड में नल नहीं और खाली स्ट्रिंग पास कर रहे हैं। लेकिन यह अशक्त का सही उपयोग नहीं है। यहाँ नल का उपयोग है। कहते हैं कि आपको एक विक्रेता से एक फ़ाइल मिलती है

नाम | लिंग | शहर

बॉब || लॉस एंजेलिस

यदि लिंग आपके द्वारा निर्दिष्ट बॉब, खाली स्ट्रिंग और लॉस एंजिल्स में तालिका में नहीं है। अब आपको यह बताने देता है कि आपको फ़ाइल मिल गई है और इसका प्रारूप बदल गया है और लिंग अब शामिल नहीं है लेकिन अतीत में था।

नाम | शहर

बॉब | सिएटल

खैर अब चूंकि लिंग को शामिल नहीं किया गया है, मैं अशक्त उपयोग करूंगा। वर्चर्स मुद्दों के बिना इसका समर्थन करते हैं।

दूसरी ओर चार अलग है। आपको हमेशा अशक्त भेजना होगा। यदि आप कभी खाली स्ट्रिंग भेजते हैं, तो आप एक ऐसे क्षेत्र के साथ समाप्त हो जाएंगे, जिसमें रिक्त स्थान हैं।

मैं लगभग 20 वर्षों के विकास में सभी कीड़े के साथ जा सकता था, जिन्हें मुझे चार से ठीक करना था।


2

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


2

यह क्लासिक स्पेस बनाम परफॉर्मेंस ट्रेडऑफ है।

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

तो, अगर स्पेस कोई समस्या नहीं है, तो चार प्रदर्शन के लिए बेहतर हैं, लेकिन यदि आप डेटाबेस का आकार कम रखना चाहते हैं, तो varchars बेहतर हैं।


2

विखंडन। चार आरक्षित स्थान और वरचर नहीं है। अद्यतन को समायोजित करने के लिए पृष्ठ विभाजन की आवश्यकता हो सकती है।


कई अन्य कारकों के कारण, CHARकॉलम अपडेट करते समय एक पेज विभाजन हो सकता है ।
रिक जेम्स

1

जब varchar मानों का उपयोग करते हुए SQL सर्वर को उस कॉलम के बारे में कुछ जानकारी संग्रहीत करने के लिए प्रति पंक्ति अतिरिक्त 2 बाइट्स की आवश्यकता होती है, जबकि यदि आप char का उपयोग करते हैं तो आपको इसकी आवश्यकता नहीं है जब तक कि आप


0

कुछ SQL डेटाबेस में, VARCHAR को ऑफ़सेट्स को ऑप्टिमाइज़ करने के लिए इसके अधिकतम आकार के लिए गद्देदार किया जाएगा, यह फुल टेबल स्कैन और इंडेक्स को गति देने के लिए है।

इसके कारण, आपके पास CHAR (200) की तुलना में VARCHAR (200) का उपयोग करके कोई स्थान बचत नहीं है


3
कौन-कौन से डेटाबेस VARCHAR को इस तरह लागू करते हैं?
ट्रॉल्स अरविन

5
गंभीरता से, क्या डेटाबेस इसे लागू करता है? आप जो वर्णन करते हैं, वह सामान्यतः CHAR पर लागू होता है, VARCHAR पर नहीं।
रिचर्ड सिमेस

mysql varchar को char में बदल देगा यदि char के और varchar के एक ही टेबल में हैं।
मालफिस्ट

MySQL टिप्पणियों की मेरी व्याख्या यह है कि यह प्राथमिक टेबल स्टोरेज पर लागू नहीं होती है, लेकिन संभवतः टेम्‍प टेबल के लिए प्रासंगिक हो सकती है। डेटा को समूहीकृत / सॉर्ट करने के लिए। dev.mysql.com/doc/refman/8.0/en/char.html stackoverflow.com/questions/262238/…
थॉमस W

0

CHAR (NCHAR) और VARCHAR (NVARCHAR) का उपयोग करने से डेटाबेस सर्वर के डेटा को स्टोर करने के तरीकों में अंतर आता है। पहले वाला पीछे चल रहे रिक्त स्थान का परिचय देता है; SQL SERVER फ़ंक्शंस में LIKE ऑपरेटर के साथ इसका उपयोग करने पर मुझे समस्या का सामना करना पड़ा है। इसलिए मुझे हर समय VARCHAR (NVARCHAR) का उपयोग करके इसे सुरक्षित बनाना होगा।

उदाहरण के लिए, यदि हमारे पास एक तालिका परीक्षण (आईडी INT, स्थिति CHAR (1)) है , और आप निम्न की तरह कुछ विशिष्ट मूल्य के साथ सभी रिकॉर्डों को सूचीबद्ध करने के लिए एक फ़ंक्शन लिखते हैं:

CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'

इस फ़ंक्शन में हम उम्मीद करते हैं कि जब हम डिफ़ॉल्ट पैरामीटर डालते हैं तो फ़ंक्शन सभी पंक्तियों को वापस कर देगा, लेकिन वास्तव में यह नहीं होता है। @Status डेटा प्रकार बदलें VARCHAR समस्या को ठीक कर देगा।


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