निम्नलिखित परिभाषाओं को समझना उपयोगी है:
-
एक वर्ण एन्कोडिंग विवरण देता है कि प्रत्येक प्रतीक को बाइनरी में कैसे दर्शाया जाता है (और इसलिए कंप्यूटर में संग्रहीत किया जाता है)। उदाहरण के लिए, प्रतीक
é
(U+00E9, एक्यूट के साथ लैटिन छोटा अक्षर E) एन्कोडेड<है /ए>0xc3a9
. के रूप में में UTF-8 (जिसे MySQLutf8
कहता है ) और0xe9
में Windows-1252 (जिसे MySQLlatin1
. कहता है )। -
एक चरित्र सेट प्रतीकों की वर्णमाला है जिसे किसी दिए गए वर्ण एन्कोडिंग का उपयोग करके दर्शाया जा सकता है। भ्रामक रूप से, शब्द का उपयोग वर्ण एन्कोडिंग के समान ही किया जाता है।
-
एक संयोजन एक वर्ण सेट पर एक आदेश है, ताकि तार की तुलना की जा सके। उदाहरण के लिए:MySQL का
latin1_swedish_ci
Collation किसी वर्ण के अधिकांश उच्चारण वाले रूपांतरों को आधार वर्ण के समतुल्य मानता है, जबकि इसकाlatin1_general_ci
संयोजन उन्हें अगले आधार वर्ण से पहले आदेश देगा लेकिन समकक्ष नहीं (अन्य, अधिक महत्वपूर्ण, अंतर भी हैं:जैसे वर्णों का क्रमå
,ए
,ओ
औरß
)।
MySQL तय करेगा कि के तहत दिए गए एक्सप्रेशन पर कौन सा कोलेशन लागू किया जाना चाहिए। भावों का मिलान :विशेष रूप से, एक कॉलम के संयोजन को एक स्ट्रिंग अक्षर के ऊपर प्राथमिकता दी जाती है।
कहां
आपकी क्वेरी का क्लॉज निम्नलिखित स्ट्रिंग्स की तुलना करता है:
-
fos_user.username
में एक मान , कॉलम के कैरेक्टर सेट (Windows-1252) में एन्कोड किया गया है और इसके संयोजन के लिए वरीयता व्यक्त करता हैlatin1_swedish_ci
(2 के जबरदस्ती मूल्य के साथ); के साथ -
स्ट्रिंग शाब्दिक
'Nrv⧧Kasi'
, कनेक्शन के कैरेक्टर सेट में एन्कोडेड (यूटीएफ -8, जैसा कि डॉक्ट्रिन द्वारा कॉन्फ़िगर किया गया है) और कनेक्शन के संयोजन के लिए वरीयता व्यक्त करनाutf8_general_ci
(4 के जबरदस्ती मूल्य के साथ)।
चूंकि इनमें से पहली स्ट्रिंग में दूसरे की तुलना में कम जबरदस्ती मान है, MySQL उस स्ट्रिंग के संयोजन का उपयोग करके तुलना करने का प्रयास करता है:latin1_swedish_ci
. ऐसा करने के लिए, MySQL दूसरी स्ट्रिंग को latin1
. में बदलने का प्रयास करता है —लेकिन ⧧
. के बाद से उस वर्ण सेट में वर्ण मौजूद नहीं है, तुलना विफल हो जाती है।
चेतावनी
कॉलम को वर्तमान में कैसे एन्कोड किया गया है, इस पर विचार करने के लिए एक पल के लिए रुकना चाहिए:आप रिकॉर्ड के लिए फ़िल्टर करने का प्रयास कर रहे हैं जहां fos_user.username
एक स्ट्रिंग के बराबर है जिसमें एक ऐसा वर्ण होता है जो नहीं उस कॉलम में मौजूद है !
अगर आपको लगता है कि कॉलम करता है ऐसे वर्ण होते हैं, तो आपने शायद कॉलम को लिखा था, जबकि कनेक्शन वर्ण एन्कोडिंग कुछ पर सेट किया गया था (उदाहरण के लिए latin1
) जिसके कारण MySQL ने प्राप्त बाइट अनुक्रम को उन वर्णों के रूप में व्याख्यायित किया जो सभी Windows-1252 वर्ण सेट में हैं।
अगर ऐसा है, तो आगे जारी रखने से पहले आपको अपना डेटा ठीक कर लेना चाहिए!
-
ऐसे कॉलम को कैरेक्टर एन्कोडिंग में कनवर्ट करें जो डेटा इंसर्शन पर इस्तेमाल किया गया था, अगर मौजूदा एन्कोडिंग से अलग है:
ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET foo;
-
ऐसे कॉलम से जुड़ी एन्कोडिंग जानकारी को
बाइनरी
. में कनवर्ट करके ड्रॉप करें वर्ण सेट:ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET binary;
-
ऐसे कॉलम के साथ संबद्ध करें, जिसमें डेटा वास्तव में उन्हें प्रासंगिक वर्ण सेट में परिवर्तित करके प्रसारित किया गया था।
ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET bar;
ध्यान दें कि, यदि मल्टी-बाइट एन्कोडिंग से कनवर्ट किया जा रहा है, तो परिवर्तित स्ट्रिंग की अधिकतम संभव लंबाई को समायोजित करने के लिए आपको कॉलम के आकार को बढ़ाने (या इसके प्रकार को बदलने) की आवश्यकता हो सकती है।
एक बार जब कोई निश्चित हो जाता है कि कॉलम सही ढंग से एन्कोड किए गए हैं, तो कोई भी यूनिकोड कोलेशन का उपयोग करके तुलना करने के लिए मजबूर कर सकता है-
-
मान
fos_user.username
. को स्पष्ट रूप से परिवर्तित करना यूनिकोड वर्ण सेट के लिए:WHERE CONVERT(fos_user.username USING utf8) = ?
-
स्ट्रिंग अक्षर को कॉलम की तुलना में कम जबरदस्ती मान रखने के लिए मजबूर करना (स्तंभ के मान का UTF-8 में एक अंतर्निहित रूपांतरण का कारण होगा):
WHERE fos_user.username = ? COLLATE utf8_general_ci
या, जैसा कि आप कहते हैं, कोई भी कॉलम को स्थायी रूप से यूनिकोड एन्कोडिंग में परिवर्तित कर सकता है और इसके संयोजन को उचित रूप से सेट कर सकता है।
सिद्धांत पर विचार यह है कि यूनिकोड एन्कोडिंग सिंगल-बाइट कैरेक्टर सेट की तुलना में अधिक स्थान लेती है, इसलिए:
-
अधिक संग्रहण की आवश्यकता हो सकती है;
-
तुलना धीमी हो सकती है; और
-
अनुक्रमणिका उपसर्ग लंबाई को समायोजित करने की आवश्यकता हो सकती है (ध्यान दें कि अधिकतम बाइट्स में है, इसलिए पहले की तुलना में कम वर्णों का प्रतिनिधित्व कर सकता है)।
साथ ही, ध्यान रखें कि, जैसा कि ALTER TABLE
सिंटैक्स
: