PostgreSQL: पाठ और varchar (वर्ण भिन्न) के बीच अंतर


619

textडेटा प्रकार और character varying( varchar) डेटा प्रकारों में क्या अंतर है ?

प्रलेखन के अनुसार

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

तथा

इसके अलावा, PostgreSQL पाठ प्रकार प्रदान करता है, जो किसी भी लम्बाई के तारों को संग्रहीत करता है। हालाँकि टाइप टेक्स्ट SQL मानक में नहीं है, लेकिन कई अन्य SQL डेटाबेस प्रबंधन प्रणालियों में भी है।

तो क्या अंतर है?

जवाबों:


745

इसमें कोई अंतर नहीं है, हुड के तहत यह सब varlena( चर लंबाई सरणी ) है।

डेपेज़ से इस लेख की जाँच करें: http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/

मुख्य आकर्षण:

इसे पूरा करने के लिए:

  • char (n) - बहुत अधिक स्थान लेता है जब मानों की तुलना में कम n(उन्हें पैड करता है n), और अनुगामी रिक्त स्थान जोड़ने के कारण सूक्ष्म त्रुटियां हो सकती हैं, साथ ही यह सीमा बदलने के लिए समस्याग्रस्त है
  • varchar (n) - लाइव वातावरण में सीमा को बदलना समस्याग्रस्त है (तालिका में फेरबदल करते समय विशेष लॉक की आवश्यकता होती है)
  • varchar - पाठ की तरह
  • पाठ - मेरे लिए एक विजेता - ओवर (एन) डेटा प्रकार क्योंकि यह उनकी समस्याओं का अभाव है, और अधिक चरचर - क्योंकि इसका अलग नाम है

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


58
@axiopisty यह एक बेहतरीन लेख है। आप बस कह सकते हैं, "क्या आप कुछ अंशों में खींच सकते हैं यदि लेख कभी नीचे जाता है?" मैंने लेख की सामग्री / निष्कर्ष को संक्षेप में प्रस्तुत करने की कोशिश की है। मुझे उम्मीद है कि यह आपकी चिंताओं को कम करने के लिए पर्याप्त है।
jpmc26

34
@axiopisty, कड़ाई से बोल रहा है, प्रारंभिक उत्तर " हुड के तहत यह सब वैरलेना था" कह रहा था , जो निश्चित रूप से उपयोगी जानकारी है जो इस जवाब को लिंक-ओनली उत्तर से अलग करती है।
ब्रूनो

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

7
@MarkHildreth अच्छा बिंदु, हालांकि आम तौर पर उस तरह की बाधाओं को इन दिनों एक आवेदन में आगे लागू किया जाता है - ताकि यूआई द्वारा नियमों (और प्रयास किए गए उल्लंघन / रिट्रीट) को आसानी से नियंत्रित किया जा सके। अगर कोई अभी भी डेटाबेस में इस तरह की बात करना चाहता है तो वे अड़चनें इस्तेमाल कर सकते हैं। देखें blog.jonanin.com/2013/11/20/postgresql-char-varchar जिसमें "VARCHAR से अधिक लचीलेपन के साथ फ़ील्ड बनाने के लिए TEXT और बाधाओं का उपयोग करने का एक उदाहरण" शामिल है।
एथन

4
Blog.jonanin.com/2013/11/20/postgresql-char-varchar @Ethan -> यह नीचे है, लेकिन यहां पाया archive.is/6xhA5
श्रीमती

115

के रूप में " चरित्र प्रकार " प्रलेखन अंक में बाहर, varchar(n), char(n), और textसभी एक ही तरह से जमा हो जाती है। एकमात्र अंतर यह है कि लंबाई की जांच करने के लिए अतिरिक्त चक्रों की आवश्यकता होती है, यदि एक दिया जाता है, और अतिरिक्त स्थान और समय की आवश्यकता होती है यदि पैडिंग के लिए आवश्यक है char(n)

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

मैंने केवल "char"निचले-मामले की वर्णमाला से चुने गए 1,000,000 यादृच्छिक की तालिका बनाई । आवृत्ति वितरण प्राप्त करने के लिए एक क्वेरी ( select count(*), field ... group by field) एक textक्षेत्र का उपयोग करते हुए एक ही डेटा पर लगभग 650 मिलीसेकंड, लगभग 760 के बारे में लेता है ।


18
तकनीकी रूप से उद्धरण प्रकार नाम का हिस्सा नहीं हैं। उन्हें चार खोजशब्द से अलग करने की आवश्यकता है।
जस

31
तकनीकी तौर पर आप सही हैं @Jasen ... कौन सा, ज़ाहिर है, सही का सबसे अच्छा प्रकार है
JohannesH

डेटाटाइप "char" नहीं है char?? यह आजकल PostgreSQL 11+ में मान्य है? ... हाँ: "प्रकार "char"(उद्धरण उद्धृत करें) चार (1) से अलग है जिसमें यह केवल भंडारण के एक बाइट का उपयोग करता है। यह आंतरिक रूप से सिस्टम कैटलॉग में एक सरलीकृत गणन प्रकार के रूप में उपयोग किया जाता है ।" , गाइड / डेटाटाइप-चरित्र
पीटर क्रूस

63

2016 के लिए अद्यतन बेंचमार्क (pg9.5 +)

और "शुद्ध एसक्यूएल" बेंचमार्क का उपयोग करना (बिना किसी बाहरी स्क्रिप्ट के)

  1. UTF8 के साथ किसी भी string_generator का उपयोग करें

  2. मुख्य बेंचमार्क:

    2.1। सम्मिलित करें

    2.2। तुलना और गिनती का चयन करें


CREATE FUNCTION string_generator(int DEFAULT 20,int DEFAULT 10) RETURNS text AS $f$
  SELECT array_to_string( array_agg(
    substring(md5(random()::text),1,$1)||chr( 9824 + (random()*10)::int )
  ), ' ' ) as s
  FROM generate_series(1, $2) i(x);
$f$ LANGUAGE SQL IMMUTABLE;

विशिष्ट परीक्षण (उदाहरण) तैयार करें

DROP TABLE IF EXISTS test;
-- CREATE TABLE test ( f varchar(500));
-- CREATE TABLE test ( f text); 
CREATE TABLE test ( f text  CHECK(char_length(f)<=500) );

एक मूल परीक्षण करें:

INSERT INTO test  
   SELECT string_generator(20+(random()*(i%11))::int)
   FROM generate_series(1, 99000) t(i);

और अन्य परीक्षण,

CREATE INDEX q on test (f);

SELECT count(*) FROM (
  SELECT substring(f,1,1) || f FROM test WHERE f<'a0' ORDER BY 1 LIMIT 80000
) t;

... और उपयोग करें EXPLAIN ANALYZE

अद्यतन किया गया 2018 (pg10)

2018 के परिणामों को जोड़ने और सिफारिशों को सुदृढ़ करने के लिए थोड़ा संपादित करें।


2016 और 2018 में परिणाम

मेरे परिणाम, औसतन, कई मशीनों और कई परीक्षणों में: सभी समान
(सांख्यिकीय रूप से कम थम मानक विचलन)।

सिफ़ारिश करना

  • textडेटाटाइप का उपयोग करें ,
    पुराने से बचें varchar(x)क्योंकि कभी-कभी यह एक मानक नहीं है, उदाहरण के लिए CREATE FUNCTIONखंड varchar(x)avoidvarchar(y)

  • एक्सप्रेस सीमाएँ (एक ही varcharप्रदर्शन के साथ !) जैसे CHECKखंड में । एक नगण्य नियंत्रण पर्वतमाला और स्ट्रिंग संरचना करने के लिए आप भी कर सकते हैं सम्मिलित / अपडेट करने में प्रदर्शन की हानि के साथ जैसेCREATE TABLE
    CHECK(char_length(x)<=10)

    CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')


तो इससे कोई फर्क नहीं पड़ता कि मैंने पाठ के बजाय अपने सभी स्तंभों को बनाया है? मैंने लंबाई निर्दिष्ट नहीं की, हालांकि कुछ केवल 4 - 5 अक्षर हैं और निश्चित रूप से 255 नहीं हैं।
खाई

1
@ ट्रेंच हाँ, इससे कोई फर्क नहीं पड़ता
फ्यूरियसफॉल्डर

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

@ ट्रेंच और रीडर: एकमात्र अपवाद तेज डेटाटाइप है "char", जो कि charपोस्टग्रेक्यूएल 11+ के आजकल में भी नहीं है । जैसा कि गाइड / डेटाटाइप-चरित्र कहता है "प्रकार "char"(उद्धरणों पर ध्यान दें) चार (1) से अलग है जिसमें यह केवल भंडारण के एक बाइट का उपयोग करता है। यह आंतरिक रूप से सिस्टम कैटलॉग में एक सरलीकृत अभिगम प्रकार के रूप में उपयोग किया जाता है ।"
पीटर क्रूस

3
2019 में अभी भी pg11 के साथ मान्य है: text> varchar (n)> text_check> char (n)
ओलिवियर रिफ्लो

37

PostgreSQL मैनुअल पर

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

मैं आमतौर पर पाठ का उपयोग करता हूं

संदर्भ: http://www.postgresql.org/docs/current/static/datatype-characterer.html


23

मेरी राय में, varchar(n)क्या इसके अपने फायदे हैं। हां, वे सभी एक ही अंतर्निहित प्रकार और सभी का उपयोग करते हैं। लेकिन, यह बताया जाना चाहिए कि PostgreSQL में अनुक्रमित इसकी आकार सीमा 2712 बाइट्स है प्रति पंक्ति ।

TL; DR: यदि आप बिना किसी अवरोध केtext प्रकार का उपयोग करते हैं और इन स्तंभों पर अनुक्रमित करते हैं, तो यह बहुत संभव है कि आप अपने कुछ स्तंभों के लिए इस सीमा को मारते हैं और जब आप डेटा डालने की कोशिश करते हैं तो त्रुटि मिलती है।varchar(n) से आप इसे रोक सकते हैं।

कुछ और विवरण: यहाँ समस्या यह है कि PostgreSQL textटाइप के लिए इंडेक्स बनाते समय कोई अपवाद नहीं देता है या varchar(n)जहां n2712 से अधिक है। हालांकि, यह त्रुटि देगा जब 2712 से अधिक के संकुचित आकार के साथ एक रिकॉर्ड डालने की कोशिश की जाती है। इसका मतलब है कि आप स्ट्रिंग के 100.000 वर्ण सम्मिलित कर सकते हैं जो दोहराए जाने वाले वर्णों द्वारा आसानी से बनाया गया है क्योंकि यह 2712 से नीचे संकुचित होगा, लेकिन आप 4000 वर्णों के साथ कुछ स्ट्रिंग सम्मिलित करने में सक्षम नहीं हो सकते क्योंकि संकुचित आकार 2712 बाइट्स से अधिक है। का उपयोग करते हुए varchar(n)जहां nनहीं है बहुत ज्यादा 2712 की तुलना में अधिक है, तो आप इन त्रुटियों से सुरक्षित हैं।


बाद में पाठ के लिए अनुक्रमण बनाने की कोशिश करने पर त्रुटियों को पोस्ट करता है केवल varchar (संस्करण के बिना) (n) के लिए काम करता है। केवल एम्बेडेड पोस्टग्रेज के साथ परीक्षण किया गया है।
arntg

2
इसके संदर्भ में: stackoverflow.com/questions/39965834/… जिसका PostgreSQL Wiki से लिंक है: wiki.postgresql.org/wiki/… में अधिकतम रो का आकार 400GB है, इससे ऐसा लगता है कि प्रति पंक्ति 2712 बाइट सीमा बताई गई है। । एक डेटाबेस के लिए अधिकतम आकार? असीमित (32 टीबी डेटाबेस मौजूद हैं) एक मेज के लिए अधिकतम आकार? एक पंक्ति के लिए 32 टीबी अधिकतम आकार? एक क्षेत्र के लिए 400 जीबी अधिकतम आकार? 1 GB किसी तालिका में अधिकतम पंक्तियाँ? असीमित
बिल वर्थिंगटन

@BillWorthington आपके द्वारा पोस्ट किए गए नंबर यद्यपि इंडेक्स डालने के कारण ध्यान में नहीं आते हैं। 2712 बाइट बीट्री की अधिकतम सीमा के बारे में है, यह एक कार्यान्वयन विवरण है ताकि आप इसे दस्तावेजों पर नहीं पा सकें। हालाँकि, आप इसे आसानी से स्वयं टेस्ट कर सकते हैं या इसे केवल "postgresql index row size इंडेक्स के लिए अधिकतम 2712 से अधिक" सर्च करके देख सकते हैं।
sotn

मैं PostgeSQL में नया हूं, इसलिए मैं विशेषज्ञ नहीं हूं। मैं एक परियोजना पर काम कर रहा हूं, जहां मैं एक तालिका में एक स्तंभ में समाचार लेख संग्रहीत करना चाहता हूं। लगता है कि टेक्स्ट कॉलम का प्रकार मैं उपयोग करूंगा। 2712 बाइट्स की कुल पंक्ति का आकार एक डेटाबेस के लिए बहुत कम लगता है, जिसे ओरेकल के समान स्तर के करीब माना जाता है। क्या मैं आपको सही ढंग से समझता हूं कि आप एक बड़े पाठ क्षेत्र को अनुक्रमित करने की बात कर रहे हैं? आप के साथ चुनौती या बहस करने की कोशिश नहीं कर रहा है, बस वास्तविक सीमाओं को समझने की कोशिश कर रहा हूं। अगर कोई इंडेक्स शामिल नहीं है, तो क्या पंक्ति की सीमा 400GB होगी जैसा कि विकी में है ?? आपकी शीघ्र प्रतिक्रिया के लिए धन्यवाद।
बिल वर्थिंगटन

1
@BillWorthington आपको पूर्ण पाठ खोज के बारे में शोध करना चाहिए। चेक इस लिंक जैसे
sotn

18

टेक्स्ट और वर्चर में अलग-अलग प्रकार के रूपांतरण होते हैं। सबसे बड़ा प्रभाव जो मैंने देखा है वह अनुगामी रिक्त स्थान को संभाल रहा है। उदाहरण के लिए ...

select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text

रिटर्न true, false, trueऔर नहीं के true, true, trueरूप में आप उम्मीद कर सकते हैं।


यह कैसे हो सकता है? यदि a = b और a = c है तो b = c।
लुकास सिल्वा

4

कुछ हद तक ओटी: यदि आप रेल का उपयोग कर रहे हैं, तो वेबपृष्ठों का मानक स्वरूप भिन्न हो सकता है। डेटा एंट्री फॉर्म के लिए textबॉक्स स्क्रॉल करने योग्य होते हैं, लेकिन character varying(रेल string) बॉक्स एक-लाइन होते हैं। शो के दृश्य आवश्यकतानुसार लंबे होते हैं।


2

Http://www.sqlines.com/postgresql/datatypes/text से एक अच्छी व्याख्या :

TEXT और VARCHAR (n) के बीच एकमात्र अंतर यह है कि आप VARCHAR कॉलम की अधिकतम लंबाई को सीमित कर सकते हैं, उदाहरण के लिए, VARCHAR (255) 255 वर्णों से अधिक लंबे तार डालने की अनुमति नहीं देता है।

TEXT और VARCHAR दोनों की ऊपरी सीमा 1 Gb है, और उनके बीच (PostgreSQL प्रलेखन के अनुसार) कोई प्रदर्शन अंतर नहीं है।


-1

character varying(n), varchar(n)- (दोनों समान)। बिना किसी त्रुटि के मूल्य को n वर्णों में काट दिया जाएगा।

character(n), char(n)- (दोनों समान)। निश्चित-लंबाई और लंबाई के अंत तक रिक्त स्थान के साथ पैड होगा।

text- असीमित लंबाई।

उदाहरण:

Table test:
   a character(7)
   b varchar(7)

insert "ok    " to a
insert "ok    " to b

हमें परिणाम मिलते हैं:

a        | (a)char_length | b     | (b)char_length
----------+----------------+-------+----------------
"ok     "| 7              | "ok"  | 2

5
जबकि MySQL चुपचाप डेटा को छोटा कर देगा जब मान स्तंभ के आकार से अधिक हो जाता है, तो PostgreSQL नहीं होगा और "वर्ण प्रकार के भिन्न होने के लिए बहुत लंबा मूल्य बढ़ाएगा (n)" त्रुटि।
gsiems
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.