पूरे डेटाबेस में CHARACTER SET (और COLLATION) कैसे बदलें?


172

हमारे पिछले प्रोग्रामर ने एक टेबल (मैसकल) में गलत कॉलेशन सेट किया। उन्होंने इसे लैटिन कोलाजेशन के साथ सेट किया, जब इसे UTF8 होना चाहिए, और अब मेरे पास मुद्दे हैं। चीनी और जापान के चरित्र के साथ हर रिकॉर्ड ??? चरित्र।

क्या कोलाज को बदलना और चरित्र का विवरण वापस प्राप्त करना संभव है?



टकराव का '??? ’से क्या लेना-देना है अक्षरों का समूह? मुझे लगा कि चरित्र सेट के साथ क्या करना है?
पीटरचूला

मैं इरादे को प्रतिबिंबित करने के लिए शीर्षक बदल रहा हूं। एक डेटाबेस के लिए डिफ़ॉल्ट टकराव को बदलना वांछित से बहुत कम है।
रिक जेम्स

जवाबों:


365

डेटाबेस परिवर्तन बदलें:

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8mb4_0900_ai_ci;

परिवर्तन तालिका टकराव:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8mb4_0900_ai_ci;

कॉलम कॉलम बदलना:

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8 COLLATE utf8mb4_0900_ai_ci;

utf8mb4_0900_ai_ciमतलब के हिस्से क्या हैं ?

3 bytes -- utf8
4 bytes -- utf8mb4 (new)
v4.0 --   _unicode_
v5.20 --  _unicode_520_
v9.0 --   _0900_ (new)
_bin      -- just compare the bits; don't consider case folding, accents, etc
_ci       -- explicitly case insensitive (A=a) and implicitly accent insensitive (a=á)
_ai_ci    -- explicitly case insensitive and accent insensitive
_as (etc) -- accent-sensitive (etc)
_bin         -- simple, fast
_general_ci  -- fails to compare multiple letters; eg ss=ß, somewhat fast
...          -- slower
_0900_       -- (8.0) much faster because of a rewrite

और जानकारी:


4
खबरदार CHARACTER SET utf8लागू हो जाएगी utf8_general_ci, लेकिन आप भी इस तरह मिलान परिभाषित कर सकते हैं ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci;यदि आवश्यक हो तो
KCD

1
... और मैं आपको इसकी जांच करने की सलाह देता हूंcreate table testit(a varchar(1)); show create table testit \G drop table testit;
केसीडी

2
बस यह उल्लेख करना चाहते हैं कि दूसरा टकराव को बदल देगा utf8_general_ci; आप के लिए यह बदलना चाहते हैं utf8_unicode_ci, तो आप मिलान परिभाषित कर सकते हैं: ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;। यह टेबलों पर ठीक वैसे ही काम करता है जैसे यह डेटाबेस पर काम करता है, जैसा @KCD ने बताया है।
समझदार

9
पूर्ण utf8 समर्थन के लिए निम्नलिखित करना बेहतर है ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci। आपको अन्य दो कथनों के लिए भी ऐसा ही करना चाहिए।
ग्रिस्सो

क्या आपको वास्तव में "ALTER TABLE <table_name> MODIFY <column_name> ..." का उपयोग करने की आवश्यकता है। Dev.mysql.com/doc/refman/5.5/en/alter-table.html के अनुसार ऐसा लगता है कि "ALTER TABLE <table_name> CONVERT TO CHARACTER SET ..." कॉलम भी बदलता है? या शायद मैं मैनुअल को सही ढंग से नहीं पढ़ / समझ रहा हूँ।
hansfn

49

सभी डेटाबेस / टेबल / कॉलम को बदलने का तरीका। इन प्रश्नों को चलाएं और वे बाद के सभी प्रश्नों को आउटपुट करके आपके संपूर्ण स्कीमा को utf8 में बदल देंगे। उम्मीद है की यह मदद करेगा!

- परिवर्तन डिफ़ॉल्ट डिफ़ॉल्ट Collation

SELECT DISTINCT concat('ALTER DATABASE `', TABLE_SCHEMA, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.tables
where TABLE_SCHEMA like  'database_name';

- बदलें टेबल Collation / चार सेट

SELECT concat('ALTER TABLE `', TABLE_SCHEMA, '`.`', table_name, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.tables
where TABLE_SCHEMA like 'database_name';

- COLUMN Collation / चार सेट बदलें

SELECT concat('ALTER TABLE `', t1.TABLE_SCHEMA, '`.`', t1.table_name, '` MODIFY `', t1.column_name, '` ', t1.data_type , '(' , t1.CHARACTER_MAXIMUM_LENGTH , ')' , ' CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.columns t1
where t1.TABLE_SCHEMA like 'database_name' and t1.COLLATION_NAME = 'old_charset_name';

अच्छा। ! यह लगभग एक घंटे है कि मैं एक ही समस्या को हल करने की कोशिश कर रहा हूं। मैं इन 3 आदेशों का उपयोग करता हूं, और मैंने देखा कि चारसेट में परिवर्तन हुआ था। लेकिन मुख्य समस्या मेरे लिए शेष है। अगर मैंने सीधे डेटाबेस में लिखा है तो मेरे ब्राउज़र में सब कुछ अच्छा है। लेकिन अगर मैंने वेबसाइट फॉर्म में कुछ सामग्री जोड़ी है, तो डेटाबेस में परिणाम सिर्फ ?????? है। क्या मुझे इस पर विचार करना चाहिए? मेरा वेब ऐप एक .NET MVC ऐप है।
टाप्स

भविष्य की परियोजनाओं के लिए उपयोगी प्रश्नों को सहेजना।
मैनटैक्स

मैंने कुछ संपादन सुझाए हैं क्योंकि ये स्वचालित प्रश्न अभी तक उपयोग करने के लिए काफी सुरक्षित नहीं थे। CHARACTER_MAXIMUM_LENGTH के साथ अभी भी एक समस्या है: जब आप जैसे कि latin1_swiki_ci से utf8_unicode_ci तक बदलते हैं तो मूल एक बहुत अधिक हो सकता है।
रूबेन

1
यह एक उत्कृष्ट उत्तर है। मेरे पास तीन टिप्पणियां / प्रश्न हैं: 1) COLUMN- कोड में "t1" का उपयोग क्यों? मुझे इसकी कोई आवश्यकता नहीं दिख रही है। 2) क्यों "t1.data_type, '(', t1.CHARACTER_MAXIMUM_LENGTH, ')'" और न केवल "t1.column_type"? 3) ऊपरी मामले और निचले मामले का मिश्रण क्यों - TABLE_SCHEMA बनाम table_name और इतने पर?
hansfn

25

खबरदार कि मैसकल में, utf8कैरेक्टर सेट असली UTF8 कैरेक्टर सेट का एक सबसेट है। स्टोरेज के एक बाइट को बचाने के लिए, मेसिक्ल टीम ने यूटीएफ 8 पात्रों के केवल तीन बाइट्स को पूरे चार-बाइट्स के बजाय स्टोर करने का निर्णय लिया। इसका मतलब है कि कुछ पूर्व एशियाई भाषा और इमोजी पूरी तरह से समर्थित नहीं हैं। सुनिश्चित करने के लिए आप सभी UTF8 वर्ण, स्टोर का उपयोग कर सकते utf8mb4डेटा प्रकार, और utf8mb4_binया utf8mb4_general_ciMySQL में।


1
अब तक, इसके utf8mb4_unicode_ciबजाय इसका उपयोग करने की अनुशंसा की जाती है utf8mb4_general_ci। देखें stackoverflow.com/questions/766809/... और drupal.stackexchange.com/questions/166405/...
रॉबिन वैन Baalen

6

डेविड व्हिटकर ने जो पोस्ट किया है, उसे जोड़कर, मैंने एक ऐसी क्वेरी बनाई है जो संपूर्ण तालिका और कॉलम को बदल देती है जो प्रत्येक टेबल को बदल देगा। इसे चलाना एक अच्छा विचार हो सकता है

SET SIONION group_concat_max_len = 100000;

यह सुनिश्चित करने के लिए कि आपका समूह कॉनैट बहुत छोटी सीमा से अधिक नहीं है जैसा कि यहां देखा गया है

     SELECT a.table_name, concat('ALTER TABLE ', a.table_schema, '.', a.table_name, ' DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci, ',
        group_concat(distinct(concat(' MODIFY ',  column_name, ' ', column_type, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ', if (is_nullable = 'NO', ' NOT', ''), ' NULL ',
        if (COLUMN_DEFAULT is not null, CONCAT(' DEFAULT \'', COLUMN_DEFAULT, '\''), ''), if (EXTRA != '', CONCAT(' ', EXTRA), '')))), ';') as alter_statement
    FROM information_schema.columns a
    INNER JOIN INFORMATION_SCHEMA.TABLES b ON a.TABLE_CATALOG = b.TABLE_CATALOG
        AND a.TABLE_SCHEMA = b.TABLE_SCHEMA
        AND a.TABLE_NAME = b.TABLE_NAME
        AND b.table_type != 'view'
    WHERE a.table_schema = ? and (collation_name = 'latin1_swedish_ci' or collation_name = 'utf8mb4_general_ci')
    GROUP BY table_name;

पिछले उत्तर के बीच एक अंतर यह है कि वह ut8mb4 के बजाय utf8 का उपयोग कर रहा था और t1.data_type का उपयोग करके t1.CHARACTER_MAXIMUM_LENGTH के लिए काम नहीं किया। साथ ही, मेरी क्वेरी विचारों को बाहर करती है, क्योंकि उन्हें अलग से बदलना होगा।

मैंने केवल एक सरणी के रूप में इन सभी अलर्ट को वापस करने के लिए एक पर्ल स्क्रिप्ट का उपयोग किया और उन पर पुनरावृत्त किया, उन स्तंभों को तय किया जो बहुत लंबे थे (आम तौर पर वे varchar (256) थे जब डेटा में आम तौर पर केवल 20 वर्ण होते थे ताकि यह एक आसान फिक्स था )।

मैंने पाया कि लैटिन 1 से परिवर्तन करते समय कुछ डेटा दूषित हो गया था -> utf8mb4। यह प्रतीत होता है कि utf8 स्तंभों में लैटिन 1 वर्णों को कूटबद्ध किया गया है जो रूपांतरण में नासमझ हो जाएगा। मैं बस उन कॉलमों से डेटा रखता था जिन्हें मैं जानता था कि पहले और बाद में परिवर्तन से स्मृति में एक मुद्दा बनने जा रहा था और उनकी तुलना की और डेटा को ठीक करने के लिए अपडेट स्टेटमेंट तैयार किए।


4

यहाँ प्रक्रिया का अच्छी तरह से वर्णन करता है। हालाँकि, कुछ पात्र जो लैटिन अंतरिक्ष में फिट नहीं थे, हमेशा के लिए चले गए। UTF-8 लैटिन 1 का एक सुपरसेट है। उलटा नहीं। अधिकांश सिंगल बाइट स्पेस में फिट होंगे, लेकिन कोई भी अपरिभाषित नहीं होगा (लैटिन 1 की सूची की जांच करें - सभी 256 वर्ण परिभाषित नहीं हैं, जो कि mysql की लैटिन 1 परिभाषा पर निर्भर करता है)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.