सितंबर 2021 संपादित करें:मैं कुछ वर्षों से MySQL 8.0 का उपयोग कर रहा हूं, इसलिए यहां कुछ अद्यतन जानकारी दी गई है।
MySQL मैनुअल में अब एक बहुत ही जानकारीपूर्ण पेज utf8mb3
. के बीच रूपांतरण के संबंध में (वर्तमान में utf8
. के रूप में भी जाना जाता है ) और utf8mb4
. utf8mb3
बहिष्कृत है और हटा दिया जाएगा
अंततः; और जब इसे हटा दिया जाता है, तो इसका वर्तमान उपनाम, utf8
, utf8mb4
. को संदर्भित करेगा इसके बजाय।
बहिष्कृत utf8mb3
. के साथ , आप एक इंडेक्स में 255 वर्णों तक स्टोर कर सकते हैं, जबकि utf8mb4
. के साथ , 191 तक, COMPACT
. का उपयोग करते समय या REDUNDANT
पंक्ति प्रारूप।
COMPRESSED
के साथ या DYNAMIC
पंक्ति प्रारूप, अनुक्रमणिका कुंजी उपसर्ग 3072 बाइट्स तक हो सकते हैं। उनके साथ, आप utf8mb3
. के लिए अधिकतम 1024 वर्णों को अनुक्रमित कर सकते हैं , और utf8mb4
. के लिए 768 वर्ण ।
नीचे मेरा पिछला उत्तर है, जो वर्णों . की संख्या के पीछे के कुछ तर्क की व्याख्या करता है आप बाइट्स . की संख्या बनाम अनुक्रमित कर सकते हैं ।
मुझे अपने शोध के कारण अपने उत्तर को संशोधित करना होगा। मैंने मूल रूप से इसे (स्वयं को उद्धृत करते हुए) पोस्ट किया था:
<ब्लॉकक्वॉट>मेरा मानना है कि इसका उत्तर यह है कि आप यह नहीं जान सकते कि सूचकांक में कितने वर्ण होंगे क्योंकि आप यह नहीं जान सकते कि आपके वर्ण कितने बाइट होंगे (जब तक कि आप मल्टी-बाइट वर्णों को बाहर करने के लिए कुछ नहीं करते)।
और मुझे यकीन नहीं है, लेकिन यह अभी भी सही हो सकता है, लेकिन बिल्कुल वैसा नहीं जैसा मैं सोच रहा था।
यहाँ सही उत्तर है:
MySQL प्रति utf8 वर्ण में 3 बाइट्स ग्रहण करता है। 255 वर्ण अधिकतम अनुक्रमणिका आकार है जिसे आप प्रति स्तंभ निर्दिष्ट कर सकते हैं, क्योंकि 256x3=768, जो 767 बाइट सीमा को तोड़ता है।
यदि आप अनुक्रमणिका आकार निर्दिष्ट नहीं करते हैं, तो MySQL अधिकतम आकार (अर्थात 255 प्रति स्तंभ) चुनता है। utf8 स्तंभ पर एक UNIQUE बाधा नहीं डाली जा सकती, जिसकी लंबाई 255 से अधिक है, क्योंकि एक अद्वितीय अनुक्रमणिका में संपूर्ण सेल मान होना चाहिए। लेकिन एक नियमित अनुक्रमणिका का उपयोग किया जा सकता है - यह केवल पहले 255 वर्णों (या पहले 767 बाइट्स?) को अनुक्रमित करेगा। और यहीं मेरे लिए अभी भी कुछ रहस्य है।
रहस्य:मैं देख सकता हूं कि MySQL सुरक्षा के लिए प्रति वर्ण 3 बाइट्स क्यों मानता है, क्योंकि अन्यथा UNIQUE बाधा को तोड़ा जा सकता है। लेकिन दस्तावेज़ यह सुझाव देते प्रतीत होते हैं कि सूचकांक वास्तव में बाइट्स में आकार में है, वर्ण नहीं। तो, मान लीजिए कि आपने 255 एक वर्चर पर चार (765 बाइट) अनुक्रमणिका(256 ) कॉलम। यदि आपके द्वारा संग्रहीत वर्ण सभी ASCII, 1-बाइट वर्ण, जैसे A-Z, a-z, 0-9 हैं, तो आप पूरे कॉलम को 767 बाइट इंडेक्स में फिट कर सकते हैं। और ऐसा लगता है कि वास्तव में ऐसा ही होगा।
पात्रों, बाइट्स आदि के बारे में मेरे मूल उत्तर से कुछ और जानकारी नीचे दी गई है।
विकिपीडिया के अनुसार , UTF-8 वर्ण 1,2, 3, या 4 बाइट लंबा हो सकता है। लेकिन, यह mysql प्रलेखन , अधिकतम वर्ण आकार 3 बाइट्स है, और इसलिए 255 वर्णों से अधिक का कोई भी स्तंभ अनुक्रमणिका अनुक्रमणिका उस बाइट सीमा को प्रभावित कर सकती है। लेकिन जैसा कि मैं इसे समझता हूं, ऐसा नहीं हो सकता है। यदि आपके अधिकांश वर्ण ASCII श्रेणी में हैं, तो आपके वर्ण का औसत आकार 1 बाइट के करीब होगा। यदि आपका औसत वर्ण आकार, उदाहरण के लिए, 1.3 बाइट्स (ज्यादातर 1 बाइट, लेकिन 2-3 बाइट वर्णों की एक महत्वपूर्ण संख्या) है, तो आप 767/1.3 की अनुक्रमणिका निर्दिष्ट कर सकते हैं
इसलिए, यदि आप अधिकतर 1-बाइट वर्णों को संग्रहीत कर रहे हैं, तो आपकी वास्तविक वर्ण सीमा अधिक होगी:767 / 1.3 =590। लेकिन यह पता चला है कि यह काम करने का तरीका नहीं है। 255 वर्णों की सीमा है।
जैसा कि इस MySQL दस्तावेज़ में बताया गया है ,
<ब्लॉकक्वॉट>उपसर्ग सीमाएँ बाइट्स में मापी जाती हैं, जबकि INDEX स्टेटमेंट में उपसर्ग की लंबाई की व्याख्या गैर-बाइनरी डेटा प्रकारों (CHAR, VARCHAR, TEXT) के लिए वर्णों की संख्या के रूप में की जाती है। मल्टी-बाइटकैरेक्टर सेट का उपयोग करने वाले कॉलम के लिए उपसर्ग लंबाई निर्दिष्ट करते समय इसे ध्यान में रखें।
ऐसा लगता है कि MySQL लोगों को गणना/गेस्टिमेशन करने की सलाह दे रहा है जैसे मैंने वर्चर कॉलम के लिए आपके मुख्य आकार को निर्धारित करने के लिए किया था। लेकिन वास्तव में आप नहीं कर सकते हैं utf8 कॉलम के लिए 255 से बड़ा इंडेक्स निर्दिष्ट करें।
अंत में, यदि आप मेरे दूसरे लिंक को फिर से देखें, तो यह भी है:
<ब्लॉकक्वॉट>जब innodb_large_prefix कॉन्फ़िगरेशन विकल्प सक्षम होता है, तो यह लंबाई सीमा 3072 बाइट्स तक बढ़ा दी जाती है, इनो डीबी तालिकाओं के लिए जो डायनामिक और संपीड़ित पंक्ति स्वरूपों का उपयोग करते हैं।
तो ऐसा लगता है कि यदि आप चाहें तो थोड़ी सी ट्वीकिंग के साथ आप बहुत बड़े इंडेक्स प्राप्त कर सकते हैं। बस सुनिश्चित करें कि पंक्ति प्रारूप गतिशील या संपीड़ित हैं। आप शायद उस स्थिति में 1023 या 1024 वर्णों की एक अनुक्रमणिका निर्दिष्ट कर सकते हैं।
वैसे, यह पता चला है कि आप [utf8mb4 वर्ण सेट] [4] का उपयोग करके 4-बाइट वर्णों को संग्रहीत कर सकते हैं। utf8 वर्ण सेट स्पष्ट रूप से केवल ["विमान 0" वर्ण [5] संग्रहीत करता है।संपादित करें:
मैंने बस एक वर्चर (511) कॉलम पर एक छोटे से (1) कॉलम के साथ एक समग्र इंडेक्स बनाने की कोशिश की और त्रुटि संदेश मिला कि अधिकतम इंडेक्स आकार 767 बाइट्स था। यह मुझे विश्वास दिलाता है कि MySQL मानता है कि utf8 वर्ण सेट कॉलम में प्रति वर्ण 3 बाइट्स (अधिकतम) होंगे, और आपको अधिकतम 255 वर्णों का उपयोग करने की अनुमति मिलती है। लेकिन शायद यह केवल समग्र अनुक्रमणिका के साथ है। जैसे ही मुझे और पता चलेगा मैं अपना जवाब अपडेट कर दूंगा। लेकिन अभी के लिए मैं इसे एक संपादन के रूप में छोड़ रहा हूँ।