У меня есть решение, которое преобразует базы данных и таблицы, выполнив несколько команд. Он также преобразует все столбцы типа varchar
, text
, tinytext
, mediumtext
, longtext
, char
. Вы также должны сделать резервную копию базы данных на случай, если что-то сломается.
Скопируйте следующий код в файл с именем preAlterTables.sql:
use information_schema;
SELECT concat("ALTER DATABASE `",table_schema,"` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name,"` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema, table_name;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type,"(",character_maximum_length,") CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('varchar','char');
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type," CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('text','tinytext','mediumtext','longtext');
Замените все вхождения yourDbName на базу данных, которую вы хотите преобразовать. Затем запустите:
mysql -uroot < preAlterTables.sql | egrep '^ALTER' > alterTables.sql
Это сгенерирует новый файл alterTables.sql со всеми запросами, необходимыми для преобразования базы данных. Запустите следующую команду, чтобы начать преобразование:
mysql -uroot < alterTables.sql
Вы также можете настроить это для работы с несколькими базами данных, изменив условие для table_schema. Например table_schema like "wiki_%"
, преобразует все базы данных с префиксом имени wiki_
. Для преобразования всех баз данных замените условие на table_type!='SYSTEM VIEW'
.
Проблема, которая может возникнуть. У меня было несколько столбцов varchar (255) в ключах mysql. Это вызывает ошибку:
ERROR 1071 (42000) at line 2229: Specified key was too long; max key length is 767 bytes
Если это произойдет, вы можете просто изменить столбец на меньший, например, varchar (150), и снова запустить команду.
Обратите внимание : этот ответ преобразует базу данных utf8mb4_unicode_ci
вместо того utf8mb4_bin
, что задано в вопросе. Но вы можете просто заменить это.
mysql -uroot -pThatrootPassWord < alterTables.sql
работает. И, как вы уже заметили, utf8mb4_bin - это то, что, помимо прочего, рекомендует nextcloud.Я использовал следующий сценарий оболочки. Он принимает имя базы данных в качестве параметра и преобразует все таблицы в другую кодировку и сопоставление (заданное другими параметрами или значением по умолчанию, определенным в сценарии).
источник
Я написал бы скрипт (на Perl или что-то еще), чтобы использовать information_schema (TABLES и COLUMNS) для обхода всех таблиц и выполнять MODIFY COLUMN для каждого поля CHAR / VARCHAR / TEXT. Я бы собрал все MODIFY в один ALTER для каждой таблицы; это будет более эффективным.
Я думаю (но не уверен), что предложение Райхана только меняет значение по умолчанию для таблицы.
источник
Столкнулся с этой ситуацией; вот подход, который я использовал для преобразования моей базы данных:
Во-первых, вам нужно отредактировать,
my.cnf
чтобы сделать соединение с базой данных по умолчанию (между приложениями и MYSQL) utf8mb4_unicode_ci совместимым. Без этих символов, таких как emojis и аналогичные, представленные вашими приложениями, вы не попадете в ваши таблицы в правильных байтах / кодировке (если в параметрах CNN БД вашего приложения не указано соединение utf8mb4).Инструкции приведены здесь .
Выполните следующий SQL (не нужно готовить SQL для изменения отдельных столбцов,
ALTER TABLE
операторы сделают это).Перед тем, как выполнить приведенный ниже код, замените «DbName» на свое фактическое имя БД.
Соберите и сохраните вывод вышеупомянутого SQL в точечный файл sql и выполните его.
Если вы получаете сообщение об ошибке
#1071 - Specified key was too long; max key length is 1000 bytes.
вместе с проблемным именем таблицы, это означает, что индексный ключ для некоторого столбца этой таблицы (который должен был быть преобразован в charstring MB4) будет очень большим, следовательно, столбец Varchar должен быть <= 250, так что его Ключ индекса будет максимум 1000 байтов. Проверьте столбцы, по которым у вас есть индексы, и если один из них является varchar> 250 (скорее всего, 255), тоШаг 1: проверьте данные в этом столбце, чтобы убедиться, что максимальный размер строки в этом столбце <= 250.
Пример запроса:
Шаг 2: если максимальная длина строки данных индексированного столбца <= 250, измените длину столбца на 250. Если это невозможно, удалите индекс для этого столбца.
Шаг 3: затем снова запустите запрос на изменение таблицы для этой таблицы, и теперь таблица должна быть успешно преобразована в utf8mb4.
Ура!
источник
Я написал это руководство: http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4
Из моей работы я увидел, что ALTER базы данных и таблиц недостаточно. Я должен был войти в каждую таблицу и изменить каждый из столбцов text / mediumtext / varchar.
К счастью, мне удалось написать скрипт для обнаружения метаданных баз данных MySQL, чтобы он мог циклически проходить по таблицам и столбцам и автоматически изменять их.
Длинный индекс для MySQL 5.6:
Есть одна вещь, которую вы должны иметь привилегию DBA / SUPER USER: установка параметров базы данных:
В ответах на этот вопрос есть инструкция, как установить эти параметры выше: https://stackoverflow.com/questions/35847015/mysql-change-innodb-large-prefix
Конечно, в моей статье есть инструкции, чтобы сделать это тоже.
Для MySQL версии 5.7 или новее , innodb_large_prefix включен по умолчанию, а innodb_file_format также является Barracuda по умолчанию.
источник
Для людей, которые могут столкнуться с этой проблемой, лучшее решение - сначала изменить столбцы в двоичный тип, в соответствии с этой таблицей:
И после этого измените столбец до его прежнего типа и с вашим желаемым набором символов.
Например.:
Я попробовал в нескольких латинских таблицах, и это сохранило все диакритические знаки.
Вы можете извлечь этот запрос для всех столбцов, которые делают это:
источник
Я сделал скрипт, который делает это более или менее автоматически:
источник