जब एक MySQL क्लाइंट सर्वर से इंटरैक्ट करता है:
-
सर्वर केवल बाइट्स की एक स्ट्रिंग के रूप में कोई पाठ प्राप्त करता है; क्लाइंट ने इसे पहले बताया होगा कि इस तरह के टेक्स्ट को कैसे एन्कोड किया जाएगा।
-
अगर सर्वर को उस टेक्स्ट को एक टेबल में स्टोर करना है, तो उसे इसे संबंधित कॉलम (यदि अलग है) के एन्कोडिंग में ट्रांसकोड करना होगा।
-
यदि क्लाइंट बाद में ऐसे टेक्स्ट को पुनः प्राप्त करना चाहता है, तो सर्वर को इसे क्लाइंट द्वारा अपेक्षित एन्कोडिंग में ट्रांसकोड करना होगा।
यदि चरण 1 और 3 में क्लाइंट द्वारा उपयोग किए गए एन्कोडिंग समान . हैं (जो आम तौर पर मामला होता है, खासकर जब दोनों मामलों में क्लाइंट एक ही एप्लिकेशन होता है), तो यह अक्सर किसी का ध्यान नहीं जाता है यदि क्लाइंट किसी अन्य एन्कोडिंग का उपयोग कर रहा है जो उसने कहा था। उदाहरण के लिए, मान लें कि क्लाइंट MySQL को बताता है कि वह latin1
. का उपयोग करेगा , लेकिन वास्तव में utf8
. में डेटा भेजता है :
-
स्ट्रिंग
'Jazz–Man'
UTF-8 में सर्वर को0x4a617a7ae280934d616e
के रूप में भेजा जाता है । -
MySQL, Windows-1252 में उन बाइट्स को डिकोड करता है, उन्हें स्ट्रिंग
'Jazz–Man'
का प्रतिनिधित्व करने के लिए समझता है । -
एक
utf8
. में स्टोर करने के लिए कॉलम, MySQL स्ट्रिंग को उसके UTF-8 एन्कोडिंग में ट्रांसकोड करता है0x4a617a7ac3a2e282ace2809c4d616e
. इसेSELECT HEX(name) FROM lessons WHERE id=79510
का उपयोग करके सत्यापित किया जा सकता है । -
जब क्लाइंट मान को पुनः प्राप्त करता है, तो MySQL सोचता है कि वह इसे
latin1
. में चाहता है और इसलिए Windows-1252 एन्कोडिंग में ट्रांसकोड करता है0x4a617a7ae280934d616e
। -
जब क्लाइंट उन बाइट्स को प्राप्त करता है, तो वह उन्हें UTF-8 के रूप में डिकोड करता है और इसलिए स्ट्रिंग को
'Jazz–Man'
समझता है। ।
निष्कर्ष :क्लाइंट को कुछ भी गलत होने का एहसास नहीं होता है। समस्याओं का पता तभी चलता है जब कोई दूसरा क्लाइंट (वह जो अपने UTF-8 कनेक्शन को latin1
के रूप में गलत नहीं बताता है) ) तालिका का उपयोग करने का प्रयास करता है। आपके मामले में, यह तब हुआ जब mysqldump ने डेटा का निर्यात प्राप्त किया; --default-character-set=latin1 --skip-set-charset
का उपयोग करके विकल्प प्रभावी रूप से mysqldump को आपके एप्लिकेशन के समान टूटे हुए तरीके से व्यवहार करने के लिए मजबूर करते हैं, इसलिए यह सही ढंग से एन्कोड किए गए डेटा के साथ समाप्त हो गया।
आगे चलकर अपनी समस्या को ठीक करने के लिए, आपको यह करना होगा:
-
अपने एप्लिकेशन को कॉन्फ़िगर करें ताकि यह अपने MySQL कनेक्शन कैरेक्टर सेट को सही ढंग से सेट करे (उदाहरण के लिए
encoding: utf8
सेट करें)config/database.yml
. में रेल के लिए); -
अपने डेटाबेस में डेटा को रिकोड करें, उदा।
UPDATE lessons SET name = BINARY CONVERT(name USING latin1)
(ध्यान दें कि यह हर गलत एन्कोडेड टेक्स्ट कॉलम के लिए किया जाना चाहिए)।
यह भी ध्यान दें कि आप शायद इन दो क्रियाओं को परमाणु रूप से करना चाहेंगे, जिसके लिए कुछ विचार करने की आवश्यकता हो सकती है।