SQL varchar स्तंभ लंबाई के लिए सर्वोत्तम अभ्यास [बंद]


290

हर बार एक नया SQL टेबल सेट किया जाता है या varcharकिसी मौजूदा टेबल में एक नया कॉलम जोड़ा जाता है , मैं एक बात सोच रहा हूँ: इसके लिए सबसे अच्छा मूल्य क्या हैlength

तो, हम कहते हैं, आपके पास एक कॉलम है जिसे nameटाइप किया जाता है varchar। तो, आपको लंबाई चुननी होगी। मैं एक नाम> 20 वर्णों के बारे में नहीं सोच सकता, लेकिन आप कभी नहीं जान पाएंगे। लेकिन 20 का उपयोग करने के बजाय, मैं हमेशा अगले 2 ^ n नंबर तक गोल करता हूं। इस मामले में, मैं लंबाई के रूप में 32 चुनूंगा। मैं ऐसा इसलिए करता हूं, क्योंकि कंप्यूटर वैज्ञानिक दृष्टिकोण से, एक नंबर 2 ^ n evenमुझे अन्य संख्याओं की तुलना में अधिक दिखता है और मैं सिर्फ यह मान रहा हूं कि नीचे की वास्तुकला उन संख्याओं को दूसरों की तुलना में थोड़ा बेहतर तरीके से संभाल सकती है।

दूसरी ओर, MSSQL सर्वर उदाहरण के लिए, डिफ़ॉल्ट लंबाई मान को 50 पर सेट करता है, जब आप एक varchar कॉलम बनाने के लिए चुनते हैं। यही मुझे इसके बारे में सोचने पर मजबूर करता है। 50 क्यों? क्या यह सिर्फ एक यादृच्छिक संख्या है, या औसत कॉलम लंबाई पर आधारित है, या क्या है?

यह भी हो सकता है - या शायद - यह है कि विभिन्न SQL सर्वर कार्यान्वयन (जैसे MySQL, MSSQL, Postgres, ...) में विभिन्न सर्वोत्तम कॉलम लंबाई मान हैं।

जवाबों:


238

कोई DBMS मुझे नहीं पता है कि कोई "अनुकूलन" है जो VARCHARएक 2^nलंबाई के साथ बेहतर प्रदर्शन करेगा, जो maxकि 2 की शक्ति नहीं है।

मुझे लगता है कि जल्दी SQL सर्वर संस्करणों वास्तव में एक का इलाज किया VARCHAR 255 के साथ एक अधिकतम अधिकतम लंबाई के साथ अलग-अलग तरीके से । मुझे नहीं पता कि क्या यह अभी भी मामला है।

लगभग सभी DBMS के लिए, आवश्यक वास्तविक संग्रहण केवल आपके द्वारा इसमें डाले गए वर्णों की संख्या से निर्धारित होता है, न कि maxआपके द्वारा निर्धारित लंबाई से। तो भंडारण के दृष्टिकोण से (और सबसे अधिक शायद एक प्रदर्शन के रूप में), इससे कोई फर्क नहीं पड़ता कि आप एक कॉलम को घोषित करते हैं VARCHAR(100)या नहीं VARCHAR(500)

आपको किसी तकनीकी / भौतिक चीज़ के बजाय maxएक VARCHARकॉलम को एक प्रकार की बाधा (या व्यावसायिक नियम) के रूप में प्रदान करना चाहिए ।

PostgreSQL के लिए सबसे अच्छा सेटअप textलंबाई प्रतिबंध के बिना उपयोग करना है और CHECK CONSTRAINTजो आपके व्यवसाय के लिए आवश्यक वर्णों की संख्या को सीमित करता है।

यदि वह आवश्यकता बदल जाती है, तो तालिका को बदलने की तुलना में चेक बाधा को बदलना बहुत तेज है (क्योंकि तालिका को लिखित होने की आवश्यकता नहीं है)

वही ओरेकल और अन्य के लिए लागू किया जा सकता है - ओरेकल VARCHAR(4000)में textहालांकि इसके बजाय होगा ।

मुझे नहीं पता कि SQL सर्वर में VARCHAR(max)और इसके बीच भौतिक संग्रहण अंतर है या नहीं VARCHAR(500)। लेकिन जाहिर तौर पर varchar(max)इसकी तुलना में प्रदर्शन प्रभाव पड़ता है varchar(8000)

इस लिंक को देखें (Erwin Brandstetter द्वारा एक टिप्पणी के रूप में पोस्ट किया गया)

2013-09-22 को संपादित करें

बिग बॉस की टिप्पणी के बारे में:

9.2 से पहले के पोस्टग्रैज संस्करण में (जो तब उपलब्ध नहीं था जब मैंने प्रारंभिक उत्तर लिखा था) स्तंभ की परिभाषा में बदलाव ने पूरी तालिका को फिर से लिखा था , उदाहरण के लिए यहां देखें । 9.2 के बाद से यह मामला नहीं है और एक त्वरित परीक्षण ने पुष्टि की है कि 1.2 मिलियन पंक्तियों वाली तालिका के लिए स्तंभ का आकार बढ़ाने में वास्तव में केवल 0.5 सेकंड का समय लगा है।

ओरेकल के लिए यह सच भी प्रतीत होता है, एक बड़ी तालिका के varcharकॉलम को बदलने में लगने वाले समय को देखते हुए । लेकिन मुझे उसके लिए कोई संदर्भ नहीं मिला।

MySQL के लिए मैनुअल कहता है " ज्यादातर मामलों में, ALTER TABLEमूल तालिका की एक अस्थायी प्रतिलिपि बनाता है "। और मेरे स्वयं के परीक्षण इस बात की पुष्टि करते हैं कि: ALTER TABLEएक स्तंभ पर आकार में वृद्धि करने के लिए 1.2 मिलियन पंक्तियों के साथ (उसी तरह पोस्टग्रेज के साथ मेरे परीक्षण में) 1.5 मिनट लगे। MySQL में हालांकि आप एक कॉलम में वर्णों की संख्या को सीमित करने के लिए एक चेक बाधा का उपयोग करने के लिए "वर्कअराउंड" का उपयोग नहीं कर सकते हैं

SQL सर्वर के लिए मुझे इस पर एक स्पष्ट विवरण नहीं मिल सका है, लेकिन एक varcharकॉलम के आकार को बढ़ाने के लिए निष्पादन समय (फिर से ऊपर से 1.2 मिलियन पंक्तियों की तालिका) इंगित करता है कि कोई पुनर्लेखन नहीं होता है।

2017-01-24 को संपादित करें

लगता है कि मैं (कम से कम आंशिक रूप से) SQL सर्वर के बारे में गलत था। हारून बर्ट्रेंड के इस उत्तर को देखें जो दर्शाता है कि एक nvarcharया varcharकॉलम की घोषित लंबाई प्रदर्शन के लिए बहुत बड़ा अंतर रखती है।


34
दरअसल, VARCHAR (255) और VARCHAR (500) के बीच एक अंतर है, भले ही आप इस तरह के कॉलम के अंदर 1 वर्ण डालते हों। पंक्ति के अंत में जोड़ा गया मान एक पूर्णांक होगा जो संग्रहीत डेटा की वास्तविक लंबाई को संग्रहीत करता है। VARCHAR (255) के मामले में यह 1 बाइट पूर्णांक होगा। VARCHAR (500) के मामले में यह 2 बाइट्स होगा। यह एक छोटा सा अंतर है, लेकिन किसी को इसके बारे में पता होना चाहिए। मेरे पास हाथ का कोई डेटा नहीं है कि यह प्रदर्शन को कैसे प्रभावित कर सकता है, लेकिन मुझे लगता है कि यह इतना छोटा है कि यह शोध के लायक नहीं है।
एनबी

1
@ एनबी: यही मैं SQL सर्वर के "जादू" 255 मूल्य के लिए उल्लेख कर रहा था। स्पष्टीकरण के लिए धन्यवाद।
a_horse_with_no_name

4
@ एनबी कौन से आरडीबीएमएस का जिक्र कर रहे हैं? एस क्यू एल सर्वर? प्रदर्शन पर असर पड़ता है। [N] VARCHAR (अधिकतम) [N] VARCHAR (n) की तुलना में थोड़ा धीमा प्रदर्शन करता है। मुझे हाल ही में इस साइट पर भेजा गया था । वही जो मैं जानता हूँ कि PostgreSQL के लिए सच नहीं है।
इरविन ब्रान्डेसटेटर

@ErwinBrandstetter: लिंक के लिए धन्यवाद। ऐसा लगता है varchar(max)कि शायद Oracle की तरह अधिक हैCLOB
a_horse_with_no_name

1
परिवर्तन varchar लंबाई तालिका को फिर से लिखना नहीं है। यह पूरी तरह से पूरी मेज के खिलाफ कसना लंबाई की जाँच करें जैसा कि ठीक है। यदि आप लंबाई बढ़ाते हैं, तो कुछ नहीं करना है, बस अगली प्रविष्टि या अपडेट बड़ी लंबाई को स्वीकार करेंगे। यदि आप लंबाई कम करते हैं और सभी पंक्तियाँ नए छोटे अवरोध से गुजरती हैं, तो Pg अगली आवेषण या अपडेट को केवल नई लंबाई लिखने की अनुमति देने के अलावा कोई और कार्रवाई नहीं करता है।
मणियो

70

VARCHAR(255)और VARCHAR(2)ले वास्तव में डिस्क पर अंतरिक्ष के एक ही राशि! तो इसे सीमित करने का एकमात्र कारण यह है कि यदि आपके पास छोटे होने के लिए इसकी विशिष्ट आवश्यकता है। नहीं तो उन सभी को 255 बनाओ।

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

देखें: MySQL के लिए इष्टतम varchar आकार क्या हैं?


7
उन सब को क्यों नहीं बनाया VARCHAR(MAX)? डेटाबेस को मॉडलिंग करते समय स्पेस केवल विचार नहीं है। आपके द्वारा मॉडलिंग की जा रही डोमेन को डेटा प्रकार और आकार ड्राइव करना चाहिए।
ओडेड

6
@Oded या VARCHAR(MAX)इसके समान नहीं है - varchar max एक प्रकार का डेटाटाइप है। और अपनी बात के लिए - अगर वह जानता था कि "डोमेन वह क्या मॉडलिंग कर रहा था" तो वह यह सवाल नहीं पूछेगा। स्पष्ट रूप से वह नहीं जानता कि उसका डेटा कितना बड़ा होगा, और मैं उसे आश्वस्त कर रहा हूं कि इसे पूर्ण आकार देने से कुछ नहीं होता है। varchar(255)varchar(65535)text
एरियल

4
@ एरियल: विचार करने के लिए अनुक्रमित पर मुद्दे और सीमाएँ भी हैं। (a,b,c,d)जब सभी चार कॉलम हों, तो आपके पास कोई इंडेक्स नहीं हो सकता है VARCHAR(255)
ypercube y

@ypercube यह सच है, यदि आपके कॉलम को एक इंडेक्स की आवश्यकता है, तो आपको आकारों के साथ अधिक सावधान रहने की आवश्यकता है। लेकिन अधिकांश स्तंभों को एक सूचकांक की आवश्यकता नहीं होती है, इसलिए अधिकांश समय आपको इसके बारे में चिंता करने की आवश्यकता नहीं होती है।
एरियल

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

54

जब भी मैं एक नई एसक्यूएल तालिका स्थापित करता हूं तो मुझे लगता है कि 2 ^ n अधिक "समान" होने के बारे में भी ऐसा ही है ... लेकिन यहां जवाबों को संक्षेप में देने के लिए, भंडारण स्थान पर कोई महत्वपूर्ण प्रभाव नहीं है बस varchar (2 ^ n) को परिभाषित करके या यहां तक ​​कि varchar (MAX)।

उस ने कहा, आपको अभी भी एक उच्च चर () सीमा निर्धारित करते समय भंडारण और प्रदर्शन पर संभावित प्रभाव का अनुमान लगाना चाहिए। उदाहरण के लिए, मान लें कि आप पूर्ण-पाठ अनुक्रमण के साथ उत्पाद विवरण रखने के लिए एक varchar (MAX) कॉलम बनाते हैं। यदि ९९% वर्णन केवल ५०० अक्षर लंबे हैं, और फिर अचानक आपको कोई ऐसा व्यक्ति मिलता है, जो विकिपीडिया लेखों के साथ विवरणों की जगह लेता है, तो आप अप्रत्याशित महत्वपूर्ण भंडारण और प्रदर्शन हिट देख सकते हैं।

बिल कारविन से एक और बात पर विचार करें :

एक संभावित प्रदर्शन प्रभाव है: MySQL में, अस्थायी टेबल और मेमोरी टेबल एक निश्चित लंबाई के कॉलम के रूप में वर्कर कॉलम को स्टोर करते हैं, इसकी अधिकतम लंबाई तक गद्देदार। यदि आप VARCHAR स्तंभों को आपके द्वारा आवश्यक सबसे बड़े आकार की तुलना में बहुत अधिक डिजाइन करते हैं, तो आप जितना अधिक याद करेंगे, उससे अधिक मेमोरी का उपभोग करेंगे। यह कैश दक्षता, छँटाई गति, आदि को प्रभावित करता है।

मूल रूप से, बस उचित व्यापार बाधाओं और थोड़े बड़े आकार पर त्रुटि के साथ आते हैं। जैसा कि @onedaywhen ने बताया, यूके में परिवार के नाम आमतौर पर 1-35 अक्षरों के बीच होते हैं। यदि आप इसे वर्चर (64) बनाने का निर्णय लेते हैं, तो आप वास्तव में कुछ भी चोट नहीं करने जा रहे हैं ... जब तक आप इस लड़के के परिवार के नाम को संग्रहीत नहीं कर रहे हैं जो कि 666 वर्णों तक लंबा है। उस स्थिति में, शायद varchar (1028) अधिक समझ में आता है।

और अगर यह मददगार हो, तो यहां 2 ^ 10 के माध्यम से 2 ^ 5 का विवरण क्या भरा हो सकता है:

varchar(32)     Lorem ipsum dolor sit amet amet.

varchar(64)     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie

varchar(128)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas

varchar(256)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt

varchar(512)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie

varchar(1024)   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie
                dapibus leo lobortis eleifend. Vivamus vitae diam turpis. Vivamu
                nec tristique magna, vel tincidunt diam. Maecenas elementum semi
                quam. In ut est porttitor, sagittis nulla id, fermentum turpist.
                Curabitur pretium nibh a imperdiet cursus. Sed at vulputate este
                proin fermentum pretium justo, ac malesuada eros et Pellentesque
                vulputate hendrerit molestie. Aenean imperdiet a enim at finibus
                fusce ut ullamcorper risus, a cursus massa. Nunc non dapibus vel
                Lorem ipsum dolor sit amet, consectetur Praesent ut ultrices sit

31

सबसे अच्छा मूल्य वह है जो अंतर्निहित डोमेन में परिभाषित डेटा के लिए सही है।

कुछ डोमेन के VARCHAR(10)लिए, Nameविशेषता के लिए सही है , अन्य डोमेन के VARCHAR(255)लिए सबसे अच्छा विकल्प हो सकता है।


15

A_horse_with_no_name के उत्तर को जोड़ने पर आपको निम्नलिखित रुचि मिल सकती है ...

इससे कोई फ़र्क नहीं पड़ता कि आप किसी स्तंभ को VARCHAR (100) या VACHAR (500) घोषित करते हैं।

-- try to create a table with max varchar length
drop table if exists foo;
create table foo(name varchar(65535) not null)engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length - 2 bytes for the length
drop table if exists foo;
create table foo(name varchar(65533) not null)engine=innodb;

Executed Successfully

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65533))engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65532))engine=innodb;

Executed Successfully

लंबाई बाइट (नों) और अशक्त बाइट को न भूलें:

name varchar(100) not null 1 बाइट (लंबाई) + 100 वर्ण तक (लैटिन 1) होगी

name varchar(500) not null 2 बाइट्स (लंबाई) + 500 वर्ण तक (लैटिन 1) होगी

name varchar(65533) not null 2 बाइट्स (लंबाई) + 65533 चार्ट (लैटिन 1) तक होगी

name varchar(65532) 2 बाइट्स (लंबाई) + 65532 वर्णों (लैटिन 1) + 1 नल बाइट तक होगी

उम्मीद है की यह मदद करेगा :)


आप MySQL का उपयोग कर रहे हैं, और प्रश्न MSSQL
बोगडान मार्ट

6

हमेशा अपने व्यावसायिक डोमेन विशेषज्ञ से जांच करें। यदि आप ऐसा करते हैं, तो उद्योग मानक की तलाश करें। यदि, उदाहरण के लिए, प्रश्न में डोमेन एक प्राकृतिक व्यक्ति का पारिवारिक नाम (उपनाम) है तो ब्रिटेन के व्यवसाय के लिए मैं व्यक्ति की जानकारी के लिए यूके सरकार के डेटा मानकों की सूची में जाऊंगा और पता लगाऊंगा कि परिवार का नाम 1 और 35 वर्णों के बीच होगा ।


3

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


-2

एक मायने में आप सही हैं, हालांकि 2 ^ 8 वर्णों से कम कुछ भी अभी भी डेटा के बाइट के रूप में पंजीकृत होगा।

यदि आप आधार वर्ण के लिए खाते हैं जो VARCHAR <255 के साथ कुछ भी छोड़ता है, तो अंतरिक्ष की समान मात्रा का उपभोग करना।

255 एक अच्छी आधारभूत परिभाषा है जब तक कि आप विशेष रूप से अत्यधिक इनपुट को कम करना नहीं चाहते हैं।


" हालांकि 2 ^ 8 वर्णों से कम कुछ भी अभी भी डेटा के बाइट के रूप में पंजीकृत होगा " - गलत। डेटाबेस केवल VARCHAR प्रकार में दिए गए वर्णों को संग्रहीत करता है। कॉलम घोषित करते समय कोई स्थान "पंजीकृत" नहीं है, आरक्षित या आरंभिक है ।
a_horse_with_no_name
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.