Как изменить стандартную сортировку базы данных?

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

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

Ответ 1

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

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;

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

Ответ 2

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

- Изменить настройку по умолчанию DATABASE

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

- Изменить TABLE Collation/ Char Установить

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/ Char Установить

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

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

Ответ 4

Добавляя к тому, что написал Дэвид Уиттакер, я создал запрос, который генерирует полный оператор table and columns 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 script, чтобы вернуть все эти изменения в качестве массива и повторить по ним, исправил слишком длинные столбцы (обычно они были varchar (256), когда у них обычно было только 20 символов, поэтому это было легко исправить).

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

Ответ 5

здесь хорошо описывает процесс. Однако некоторые персонажи, которые не вписывались в латинское пространство, ушли навсегда. UTF-8 является SUPERSET latin1. Не наоборот. Большинство будет вписываться в однобайтовое пространство, но любые undefined не будут (проверьте список latin1 - не все 256 символов определены, в зависимости от определения mysql latin1)