Как изменить параметры сортировки базы данных по умолчанию? - PullRequest
152 голосов
/ 06 мая 2011

Наш предыдущий программист установил неправильную сортировку в таблице (Mysql). Он настроил это с помощью латинского сопоставления, когда это должно быть UTF8, и теперь у меня есть проблемы. Каждая запись с китайским и японским характером превращается в ??? характер.

Можно ли изменить параметры сортировки и вернуть детализацию символа?

Ответы [ 5 ]

337 голосов
/ 02 марта 2012

изменить параметры сортировки базы данных:

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci;

изменить таблицу сортировки:

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

изменить параметры сортировки столбцов:

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

Дополнительная информация:

42 голосов
/ 13 мая 2015

Вот как изменить все базы данных / таблицы / столбцы. Запустите эти запросы, и они выведут все последующие запросы, необходимые для преобразования всей вашей схемы в utf8. Надеюсь, это поможет!

- Изменить сопоставление базы данных по умолчанию

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

- Изменить сопоставление ТАБЛИЦЫ / Набор символов

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';

- Изменить сопоставление столбцов / набор символов

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';
23 голосов
/ 03 марта 2015

Помните, что в Mysql набор символов utf8 является только подмножеством действительного набора символов UTF8. Чтобы сохранить один байт памяти, команда Mysql решила хранить только три байта символов UTF8 вместо полных четырех байтов. Это означает, что некоторые восточноазиатские языки и эмодзи поддерживаются не полностью. Чтобы убедиться, что вы можете сохранить все символы UTF8, используйте тип данных utf8mb4 и utf8mb4_bin или utf8mb4_general_ci в Mysql.

6 голосов
/ 17 сентября 2016

Добавляя к тому, что написал Дэвид Уиттакер, я создал запрос, который генерирует полный оператор таблицы и оператора alter, который преобразует каждую таблицу.Это может быть хорошей идеей, чтобы сначала запустить

SET SESSION group_concat_max_len = 100000;

, чтобы убедиться, что ваша группа concat не выходит за очень маленький предел, как видно здесь .

     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;

Разница здесь между предыдущим ответом состоит в том, что он использовал utf8 вместо ut8mb4 и использование t1.data_type с t1.CHARACTER_MAXIMUM_LENGTH не работает для перечислений.Кроме того, мой запрос исключает представления, поскольку их придется изменять отдельно.

Я просто использовал сценарий Perl, чтобы вернуть все эти изменения в виде массива, и перебрал их, исправив слишком длинные столбцы (обычно они былиvarchar (256), когда данные обычно содержали только 20 символов, что было легко исправить).

Я обнаружил, что некоторые данные были повреждены при изменении из latin1 -> utf8mb4.Казалось, что кодированные в столбцах utf8 латинские символы 1 в столбцах будут глупыми при преобразовании.Я просто держал данные из столбцов, которые, как я знал, будут проблемой в памяти до и после изменения, сравнивал их и генерировал операторы обновления для исправления данных.

4 голосов
/ 06 мая 2011

здесь хорошо описывает процесс.Тем не менее, некоторые символы, которые не помещались в латинице, исчезли навсегда.UTF-8 - СУПЕРСЕТЬ латыни1.Не наоборот.Большинство будет помещаться в однобайтовое пространство, но любые неопределенные не будут (проверьте список символов latin1 - не все 256 символов определены, в зависимости от определения latin1 mysql)

...