2011-04-08 15 views
7

मैं कुछ दिनों के लिए एसक्यूएल डेटा प्रकारों के बारे में शोध और पढ़ रहा हूं (मुझे पता है ... मुझे पता है, यह बहुत लंबा नहीं है) और उन चीजों में से एक जो मुझे समझने में मुश्किल है, यह है कि सर्वश्रेष्ठ डेटा कैसे चुनें विस्तारशीलता, दक्षता, और पहुंच की आसानी के लिए टाइप करें।MySQL के लिए डेटा प्रकार का चयन?

मुझे लगता है कि यह मूल डेटा प्रकार (यानी int बनाम वर्चर) चुनने के लिए बहुत सीधे है, लेकिन आप ब्लॉब और टेक्स्ट प्रकार जैसी चीज़ों के बीच कैसे चुनते हैं।

MySQL मैन पेज बहुत अच्छे हैं, लेकिन वे नहीं हैं जो हम कंप्यूटर geeks प्यार ... कुशल हैं।

मुझे लगता है कि यह बहुत ही अच्छा होगा अगर हम MySQL डेटा प्रकारों की सूची संकलित कर सकते हैं, प्रत्येक के सामान्य फायदे/नुकसान और जब यह डेटा प्रकार चुनने के लिए समझ में आता है।

+1

http://www.google.com/search?q=performance+of+mysql+data+types बांध (कुछ भी करने के लिए किया जाता है पहले पृष्ठ पर) – Ben

+0

मुझे प्रश्न पसंद है, और एक अच्छी तरह से सोचा जवाब के लिए आशा है, यह वास्तव में मेरे सर्वर पर गति में मदद कर सकता है (अगर मैंने गलत प्रकार उठाए हैं)। इस बीच, इस आलेख के साथ कुछ करने के लिए कुछ था (और गलत डेटाटाइप चुनने में समस्याएं) http://m.pinboard.in/blog/173/ – Ben

+0

@ निश्चित रूप से Google के लिए एक लिंक, आप नहीं सोचते मेरे प्रश्न को पढ़ते हुए कि मैंने कुछ समय बिताया है और सबसे अच्छा क्या है इसके बारे में पढ़ना है। समस्या यह है कि उस जानकारी का एक कुशल तरीके से संकलन नहीं किया जाता है जिसमें प्रत्येक का उपयोग कब किया जाए। यदि आप 5 या 6 लेख पढ़ते हैं तो आपको शुरू करने के लिए अच्छी जानकारी मिलती है लेकिन हम यहां विकी शैली सूची में आसानी से मेल खा सकते हैं। यह संपादन योग्य हो सकता है और Google परिणामों के बावजूद सिफ्टिंग से कहीं ज्यादा बेहतर उपयोग किया जा सकता है। खोज का सबसे अच्छा लेख peachpits है और यह अभी भी अपूर्ण है। :/मुझे लगता है कि यहां एक जवाब बहुत बेहतर हो सकता है। – austinbv

उत्तर

11

MySQL स्ट्रिंग प्रकार दो प्रकारों में आते हैं: एक चरित्र सेट लेबल के बिना और एक चरित्र सेट लेबल वाला एक।

एक निश्चित लंबाई स्ट्रिंग, अंत में रिक्त स्थान के साथ गद्देदार, CHAR (n) है। मेल खाने वाला प्रकार जिसमें कोई वर्ण सेट लेबल नहीं है BINARY (n) है। CHAR(255) CHARSET utf8 में स्ट्रिंग "हैलो" को संग्रहीत करने से 765 बाइट्स (रिक्त स्थान के साथ स्ट्रिंग को पूर्ण लंबाई तक पैड किया जाएगा, जिसे utf8 के रूप में संग्रहीत किया जाता है जो 3 बाइट्स/वर्ण का सबसे खराब केस स्पेस उपयोग 3 * 255 बाइट आवंटित करता है)।

एक या दो लंबाई बाइट्स के साथ एक परिवर्तनीय लंबाई स्ट्रिंग और कोई पैडिंग VARCHAR ((n) नहीं है। मिलान प्रकार जिसमें कोई वर्ण सेट लेबल नहीं है VARBINARY (n)। VARCHAR(255) CHARSET utf8 में स्ट्रिंग "हैलो" को संग्रहीत करना होगा 6 बाइट्स (1 लंबाई बाइट के साथ साथ वास्तविक पाठ के लिए 5 बाइट्स)। स्ट्रिंग भंडारण ク एक ही प्रकार के 10 बाइट्स (1 लंबाई बाइट प्लस 3 अक्षरों चरित्र प्रति 3 बाइट्स का उपयोग कर उन्हें प्रतिनिधित्व करने के लिए) ले जाएगा में リ ス।

mysql> select hex('クリス'), length(hex('クリス'))/2 as bytes; 
+--------------------+--------+ 
| hex('クリス')  | bytes | 
+--------------------+--------+ 
| E382AFE383AAE382B9 | 9.0000 | 
+--------------------+--------+ 
1 row in set (0.02 sec) 

एक, दो, तीन या चार लंबाई बाइट्स के साथ एक परिवर्तनीय लंबाई स्ट्रिंग TINYTEXT, टेक्स्ट, मेडियम और LARGETEXT है। मिलान प्रकार जिनके पास कोई वर्ण सेट लेबल नहीं है, वे टिनब्लोब, ब्लॉब, मेडियमब्लॉब और लार्जब्लॉब हैं।

एक पाठ/ब्लॉब की तरह प्रकार में एक VARCHAR/VARBINARY की तरह प्रकार से अलग है कि कैसे और कहाँ डेटा संग्रहीत किया जाता है, कैसे पाठ/ब्लॉब की तरह प्रकार के संस्करण और ROW_FORMAT पर निर्भर करता है InnoDB में जमा हो जाती पर जानकारी के लिए http://www.mysqlperformanceblog.com/2010/02/09/blob-storage-in-innodb/ देखना सेटिंग्स। प्रदर्शन कारणों से, आप इनो डीबी और "बराक्यूडा" -फॉर्मैट टेबल का हालिया संस्करण चाहते हैं।

MySQL किसी भी डेटा के साथ काम करने में असमर्थ है जो आकार में max_allowed_packet (डिफ़ॉल्ट: 1 एम) से बड़ा है, जब तक कि आप सर्वर की तरफ जटिल और मेमोरी तीव्र वर्कअराउंड नहीं बनाते। यह आगे प्रतिबंधित करता है कि टेक्स्ट/बीएलओबी-जैसी प्रकारों के साथ क्या किया जा सकता है, और आमतौर पर LARGETEXT/LARGEBLOB प्रकार को डिफ़ॉल्ट कॉन्फ़िगरेशन में बेकार बनाता है।

किसी चरित्र सेट लेबल (बिनरी, वर्बिनरी और% BLOB%) के बिना प्रकार के लिए, MySQL डेटा को प्राप्त करने और डिस्क पर लिखने के लिए स्वीकार करेगा। एक चरित्र सेट लेबल वाले प्रकारों के लिए, MySQL देखेंगे कि आपने अपने क्लाइंट कैरेक्टर को SET NAMES के साथ सर्वर पर सेट किया है और कॉलम परिभाषित वर्ण सेट लेबल क्या है। फिर यह कनेक्शन वर्ण सेट से कॉलम वर्ण सेट में परिवर्तित हो जाएगा और परिवर्तित डेटा लिखें। आप इसे हेक्स() फ़ंक्शन के साथ देख सकते हैं, उदा। SELECT HEX(str) FROM t WHERE id = ...

पुनः प्राप्ति पर, कनेक्शन SET NAMES के साथ सेट की घोषणा चरित्र क्या यह लिखने के समय में किया गया था से अलग हो सकता है। MySQL फिर से इस कनेक्शन के लिए घोषित वर्ण सेट के विरुद्ध कॉलम वर्ण सेट लेबल की जांच करेगा, और यदि आवश्यक हो, तो कनेक्शन वर्ण सेट में परिवर्तित हो जाएगा।

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


एक संबंधित प्रश्न अक्सर पूछे जाने पर: क्या मैं चार्ज या वचर (क्रमशः बारिश या शब्दावली) चुनूंगा?

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


एक अन्य संबंधित प्रश्न: मैं VARCHAR या पाठ मेरी स्ट्रिंग्स के लिए चुनें दूँ (VARBINARY या ब्लॉब, क्रमशः)?

कि के लिए जवाब InnoDB, बाराकुडा प्रारूप तालिकाओं का नवीनतम संस्करण और फिर पाठ/ब्लॉब उपयोग कर रहा है। इसका कारण http://www.mysqlperformanceblog.com/2011/04/07/innodb-row-size-limitation/ में लंबाई में समझाया गया है। कि का नतीजा यह है: या तो VARCHAR या पाठ/पूर्व बाराकुडा प्रारूप में ब्लॉब के साथ आप InnoDB पंक्ति आकार सीमा बह निकला आप एक ही पंक्ति में उनमें से भी कई अगर के जोखिम को चलाते हैं।


और आखिरकार: क्या मैं डेटाबेस में फ़ाइलों/छवियों/अन्य बड़े ब्लॉब या टेक्स्ट डेटा स्टोर करूं?

कि के लिए जवाब है: आम तौर पर नहीं। किसी डेटाबेस से फ़ाइलों की सेवा करना (http://mysqldump.azundris.com/archives/36-Serving-Images-From-A-Database.html) एक फाइल सिस्टम से फाइलों की तुलना में एक महंगा ऑपरेशन है। यदि संभव हो, तो आप इसके बजाय ऐसा करना चाहते हैं। कि, http://www.blobstreaming.org/ के चारों ओर एक तरीका नहीं है, लेकिन वह उन्नत प्रौद्योगिकी की आवश्यकता है कि आप अपने निष्पादन वातावरण है, जो एक की मेजबानी की स्थिति में मामला नहीं है के कुल नियंत्रण होता है।


इस दौर को बंद करने के लिए: मेमरी इंजन टेबल में कोई परिवर्तनीय लंबाई डेटा प्रकार नहीं हैं। तो अगर आप "अस्थायी का उपयोग कर" देख रहे हैं एक EXPLAIN उत्पादन में, इसका मतलब है

  • VARCHAR कि अस्थायी तालिका में CHAR में बदल जाती है
  • VARBINARY अस्थायी तालिका से तो बायनरी

में बदल जाती है यह प्रक्रिया tmp_table_size या max_heap_table_size से बड़ी हो जाती है, यह मक्खी प्रारूप में परिवर्तित मक्खी पर है और डिस्क पर जाती है।

उदाहरण: आप रूबी सक्रिय रिकॉर्ड कक्षा User परिभाषित कर रहे हैं जिसमें :string के रूप में टैग किए गए दस फ़ील्ड शामिल हैं। इनमें से प्रत्येक VARCHAR(255) CHARSET utf8 आपके Users तालिका में समाप्त होता है।

आपके कोडबेस में कहीं और, Users इस तरह से उपयोग किया जा रहा है जिसमें एक योजना using temporary शामिल है। आप तुरंत लोड के तहत डिस्क ऑपरेशंस में मर रहे हैं, क्योंकि Users तालिका की प्रत्येक पंक्ति कम से कम मेमरी में 7650 बाइट्स का उपयोग कर रही है, उनमें से अधिकतर पैडिंग के रूप में उपयोग की जाने वाली रिक्त स्थान हैं। यह अस्थायी तालिका को MyISAM में परिवर्तित करने और डिस्क पर लिखे जाने के लिए मजबूर करता है।

  • किसी भी% TEXT% या% ब्लॉब% प्रकार स्मृति में प्रतिनिधित्व नहीं किया जा सकता है, तो अस्थायी तालिका MyISAM यह पर्याप्त रूप से सीमा ऊपर कहा गया है के अनुसार स्मृति में रखा जाना करने के लिए छोटे हो गया होता, भले ही के रूप में डिस्क के लिए चला जाता है।

इसका मतलब है कि एक पाठ या ब्लॉब प्रकार और "अस्थायी का उपयोग कर" के साथ एक योजना के साथ किसी भी प्रश्न आदेश डिस्क मार अस्थायी तालिकाओं से बचने के लिए फिर से लिखा जाना चाहिए।

1

बीएलओबी बनाम टेक्स्ट के संबंध में (क्योंकि यह आपके पोस्ट में एकमात्र ठोस प्रश्न है): बीएलओबी बाइनरी डेटा के लिए है, और टेक्स्ट टेक्स्ट डेटा के लिए है।

आमतौर पर सबसे विशिष्ट प्रकार के कॉलम का उपयोग करना बहुत आसान है जो आपकी आवश्यकताओं के अनुरूप है, और जेनेरिक प्रकारों में फॉलबैक अगर उनमें से कोई भी आपके उपयोग में फिट नहीं है।

1

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

एक त्वरित गतिशील concat स्क्रिप्ट चलाने के लिए एसक्यूएल उत्पन्न करने के लिए

select CONCAT(' SELECT ', COLUMN_NAME, ' FROM ', TABLE_NAME, ' procedure analyse() ;') 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_schema ="yourDbName" 
AND DATA_TYPE ="varchar" 
AND CHARACTER_MAXIMUM_LENGTH > 190 
AND COLUMN_KEY not in (' ') ; 

** एसक्यूएल ऊपर पीकेएस का मूल्यांकन नहीं करता है - यह सोचते हैं कि वे पाठ फ़ील्ड

प्रक्रिया उपयोगी है नहीं कर रहे हैं जब बदलने के लिए की तलाश में डेटा उपयोग के आधार पर एक डेटाटाइप या एक छोटे डेटा पैकेट को स्थानांतरित या संग्रहीत करके अधिक क्षमता प्राप्त करने के लिए।

परकोना ब्लॉग में प्रक्रिया विश्लेषण का एक अच्छा कामकाजी उदाहरण है जो ड्रूपल पर लागू होता है। https://www.percona.com/blog/2009/03/23/procedure-analyse/

कि अनुसंधान से कुछ संपीड़न जो अब utf8mb4 अनुक्रमित में http://techblog.constantcontact.com/devops/space-the-final-frontier-a-story-of-mysql-compression/

संबंधित मुद्दे