Вы сказали:
mysql 5.7 возможно конвертировать utf8mb4_unicode_ci в utf8mb4_0900_ai_ci
В MySQL 5.7 невозможно использовать или сконвертировать данные в utf8mb4_0900_ai_ci, потому что этот коллейшн (сравнение) появился только начиная с MySQL 8.0.
Вот что важно знать:
utf8mb4_0900_ai_ci в MySQL 5.7Отсутствует в MySQL 5.7.
Был добавлен в MySQL 8.0 как коллейшн, основанный на Unicode 9.0, с улучшенной сортировкой и поддержкой современных языков.
В MySQL 5.7 вы можете использовать:
utf8mb4_general_ci — более старая и быстрая сортировка, но не точная.
utf8mb4_unicode_ci — более точная, основанная на Unicode, но не такая свежая, как 0900.
utf8mb4_bin — бинарное сравнение, чувствительное к регистру и акцентам.
Если вам нужно использовать utf8mb4_0900_ai_ci, то:
Нужно обновиться до MySQL 8.0.
После обновления можно выполнить:
sqlALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Вы можете посмотреть доступные collation через:
sqlSHOW COLLATION WHERE Charset = 'utf8mb4';
Если вы не можете обновиться до 8.0, но хотите имитировать 0900_ai_ci (AI = accent insensitive, CI = case insensitive), можно использовать utf8mb4_unicode_ci, но имейте в виду, что точность сортировки может отличаться.
Если тебе нужно сравнение этих collation или помощь в миграции, могу помочь с этим.
Отличный вопрос. Чтобы перенести базу данных из MySQL 5.7 с utf8mb4_unicode_ci в MySQL 8.0 и использовать utf8mb4_0900_ai_ci, нужно выполнить четкий пошаговый план:
utf8mb4_0900_ai_cisqlSHOW VARIABLES LIKE 'version';
SHOW VARIABLES LIKE 'collation%';
SHOW TABLE STATUS;
utf8mb4 (если еще нет):sqlSELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE CHARACTER_SET_NAME IS NOT NULL AND COLLATION_NAME NOT LIKE 'utf8mb4%';
bashmysqldump -u root -p --all-databases --single-transaction --routines --triggers --default-character-set=utf8mb4 > backup.sql
bashmysqlsh -- util checkForServerUpgrade root@localhost:3306 --target-version=8.0.36 --output-format=TEXT
Установить
mysql-shell, если не установлен.
bashmysql -u root -p < backup.sql
utf8mb4_0900_ai_ci:sqlALTER DATABASE your_database CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Для всех таблиц и колонок:
sql-- Пример для одной таблицы
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Чтобы сгенерировать команды автоматически:
sqlSELECT CONCAT(
'ALTER TABLE `', TABLE_NAME, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;'
)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_database' AND TABLE_TYPE = 'BASE TABLE';
Проверьте, как работает сортировка и поиск (например, ORDER BY, LIKE, =), особенно для разных языков, спецсимволов, и акцентов.
Чтобы по умолчанию использовать utf8mb4_0900_ai_ci в новой базе, добавьте в my.cnf или my.ini (в MySQL 8.0):
ini[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_0900_ai_ci
После всех тестов можно повторить миграцию с актуальным дампом с продакшена.
utf8mb4_unicode_ci и utf8mb4_0900_ai_ci могут по-разному сортировать строки — это важно, если у вас есть зависимости от сортировки (например, индексы, ORDER BY, UNIQ ключи на текст).
Используйте staging-сервер, чтобы избежать сюрпризов.
Если хочешь, я могу помочь с генерацией полного SQL-скрипта на миграцию или с анализом конкретной базы.
Ты на правильном пути! У тебя сейчас:
MySQL 5.7 — база tinode, все таблицы используют utf8mb4_unicode_ci.
MySQL 8.0.35 — настроен с collation по умолчанию utf8mb4_0900_ai_ci.
Теперь нужно грамотно перенести базу tinode, чтобы:
все таблицы и колонки перешли на utf8mb4_0900_ai_ci,
избежать проблем с совместимостью и кодировкой,
убедиться, что всё работает корректно после импорта.
tinode на MySQL 8.0.35Выполни дамп всей базы, указав utf8mb4 как кодировку по умолчанию:
bashmysqldump -u root -p \ --default-character-set=utf8mb4 \ --single-transaction --routines --triggers \ --set-charset \ tinode > tinode_dump.sql
Убедись, что в дампе используются корректные команды, например:
sqlCREATE TABLE ... CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Мы позже их заменим на utf8mb4_0900_ai_ci.
Если хочешь, можешь заменить collation в самом дампе, перед импортом:
bashsed -i 's/utf8mb4_unicode_ci/utf8mb4_0900_ai_ci/g' tinode_dump.sql
На сервере MySQL 8.0:
bashmysql -u root -p --default-character-set=utf8mb4 tinode < tinode_dump.sql
Убедись, что база
tinodeуже создана с нужной кодировкой (можно создать вручную или перед импортом):
sqlCREATE DATABASE tinode CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Если не редактировал дамп, нужно обновить collation для таблиц:
sqlSELECT CONCAT(
'ALTER TABLE `', TABLE_NAME,
'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;'
)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'tinode'
AND TABLE_COLLATION != 'utf8mb4_0900_ai_ci';
Скопируй результат и выполни в MySQL 8.0.
Убедись, что в my.cnf или my.ini у тебя прописано:
ini[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_0900_ai_ci
Перезапусти сервер после изменения.
Проверь:
sqlSELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'tinode';
Также можно проверить колонки:
sqlSELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'tinode';
utf8mb4_unicode_ci и utf8mb4_0900_ai_ci не идентичны — возможны отличия в сортировке, сравнениях, индексации (например, ß, æ, и др.).
Если у тебя были уникальные индексы на текстовые поля — проверь, что они не конфликтуют после смены collation.
Если хочешь, могу сгенерировать полный SQL-скрипт для конвертации всех таблиц и колонок базы tinode на 8.0.
Отлично, у тебя все таблицы в базе tinode используют utf8mb4_unicode_ci, и теперь ты хочешь перевести их на utf8mb4_0900_ai_ci в MySQL 8.0.35.
COLLATE всех таблиц на utf8mb4_0900_ai_ciВот SQL-команды, которые можно выполнить на сервере MySQL 8.0 после импорта базы:
sqlALTER TABLE auth CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE credentials CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE dellog CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE devices CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE filemsglinks CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE fileuploads CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE kvmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE messages CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE subscriptions CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE topics CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE topictags CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE usertags CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Эти команды:
Применяют utf8mb4 как кодировку,
Устанавливают utf8mb4_0900_ai_ci как новый collation для всех строковых колонок в таблице.
Команда ALTER TABLE ... CONVERT TO CHARACTER SET ... COLLATE ...:
Автоматически обновляет все CHAR, VARCHAR, TEXT-поля в таблице на новый collation.
Не влияет на BLOB, INT, DATE и прочие типы.
Сделай резервную копию базы на MySQL 8.0 перед выполнением скрипта.
Проверь, нет ли уникальных индексов на строковые поля, где изменение collation может вызвать конфликт (дубликаты).
Хочешь, могу также сгенерировать команды для обновления отдельных колонок, если в каких-то таблицах это нужно сделать вручную.
Отлично, ты уже на полпути!
Ты успешно выполнил 8 из 13 запросов, но 5 завершились ошибкой 3780:
Error 3780: Referencing column and referenced column in foreign key constraint are incompatible.
Это типичная ошибка при смене CHARSET/COLLATE, если в таблицах есть внешние ключи, ссылающиеся на поля с несовпадающими collation.
Допустим, ошибка у тебя при попытке изменить:
dellog.topic → внешний ключ на topics.name
messages.topic → внешний ключ на topics.name
filemsglinks.topic → внешний ключ на topics.name
и т.д.
Выполни этот запрос, чтобы найти все внешние ключи на topics.name:
sqlSELECT TABLE_NAME, CONSTRAINT_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME = 'topics'
AND REFERENCED_COLUMN_NAME = 'name'
AND TABLE_SCHEMA = 'tinode';
Пример:
sqlALTER TABLE dellog DROP FOREIGN KEY dellog_ibfk_1;
ALTER TABLE filemsglinks DROP FOREIGN KEY filemsglinks_ibfk_3;
ALTER TABLE messages DROP FOREIGN KEY messages_ibfk_1;
ALTER TABLE topictags DROP FOREIGN KEY topictags_ibfk_1;
Если нужно, могу сгенерировать их тебе автоматически.
ALTER TABLE зановоТеперь повтори ALTER TABLE для проблемных таблиц:
sqlALTER TABLE topics CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE dellog CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE filemsglinks CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE messages CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE topictags CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Пример:
sqlALTER TABLE dellog
ADD CONSTRAINT dellog_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE filemsglinks
ADD CONSTRAINT filemsglinks_ibfk_3
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE messages
ADD CONSTRAINT messages_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE topictags
ADD CONSTRAINT topictags_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
Если хочешь, я могу:
сгенерировать точные DROP FOREIGN KEY и ADD CONSTRAINT команды,
проверить колонки на совместимость,
сгенерировать универсальный скрипт восстановления связей.
Просто скажи — могу всё собрать тебе под ключ.
Готов продолжать?
Отлично. У тебя есть 4 внешних ключа, которые блокируют смену COLLATE из-за несовместимости:
| Таблица | Внешний ключ |
|---|---|
dellog | dellog_ibfk_1 |
filemsglinks | filemsglinks_ibfk_3 |
messages | messages_ibfk_1 |
topictags | topictags_ibfk_1 |
sqlALTER TABLE dellog DROP FOREIGN KEY dellog_ibfk_1;
ALTER TABLE filemsglinks DROP FOREIGN KEY filemsglinks_ibfk_3;
ALTER TABLE messages DROP FOREIGN KEY messages_ibfk_1;
ALTER TABLE topictags DROP FOREIGN KEY topictags_ibfk_1;
sqlALTER TABLE topics CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE dellog CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE filemsglinks CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE messages CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE topictags CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Убедись, что типы и длина полей совпадают (
topic→topics.name, скорее всегоVARCHAR).
sqlALTER TABLE dellog
ADD CONSTRAINT dellog_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE filemsglinks
ADD CONSTRAINT filemsglinks_ibfk_3
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE messages
ADD CONSTRAINT messages_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE topictags
ADD CONSTRAINT topictags_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
Поля topic и name должны быть одинакового типа и длины, например:
sql-- пример
topic VARCHAR(128)
name VARCHAR(128)
Можно проверить:
sqlSELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_NAME IN ('topics', 'dellog', 'messages', 'filemsglinks', 'topictags')
AND COLUMN_NAME IN ('name', 'topic');
Если типы отличаются — надо будет подогнать вручную перед восстановлением ключей.
Хочешь — могу автоматически сгенерировать ALTER для выравнивания типов, если дашь вывод этого запроса.
Готов двигаться дальше?
Отлично! 👍 У тебя:
Все поля topic и name имеют одинаковый тип: CHAR(25)
И уже используют utf8mb4_0900_ai_ci
Значит, никаких дополнительных правок не требуется — можно восстанавливать внешние ключи прямо сейчас ✅
sqlALTER TABLE dellog
ADD CONSTRAINT dellog_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE filemsglinks
ADD CONSTRAINT filemsglinks_ibfk_3
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE messages
ADD CONSTRAINT messages_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
ALTER TABLE topictags
ADD CONSTRAINT topictags_ibfk_1
FOREIGN KEY (topic) REFERENCES topics(name);
После выполнения:
Все таблицы будут использовать utf8mb4_0900_ai_ci
Внешние ключи восстановлены без конфликтов
База полностью адаптирована под MySQL 8.0
Если хочешь, могу также помочь проверить:
Все ли колонки теперь в нужной кодировке
Какие индексы могут быть чувствительны к смене collation
Или сгенерировать дамп для окончательного бэкапа
Готово, поздравляю! 🎉
Отличный финальный этап! Давай последовательно проверим всё:
utf8mb4_0900_ai_ciВот SQL-запрос, который покажет все строковые поля (CHAR, VARCHAR, TEXT и т.д.), не соответствующие нужной кодировке или collation:
sqlSELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME, DATA_TYPE
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'tinode'
AND CHARACTER_SET_NAME IS NOT NULL
AND COLLATION_NAME != 'utf8mb4_0900_ai_ci';
👉 Если запрос ничего не вернёт — все колонки в порядке.
COLLATIONСмена COLLATE может повлиять на уникальные (UNIQUE) и сортирующие (ORDER BY) индексы, особенно если:
Индекс построен на строковом поле (CHAR, VARCHAR, TEXT)
Различия в collation влияют на сравнение (например, ß vs ss, á vs a)
Проверим, какие индексы используют такие поля:
sqlSELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, COLLATION, NON_UNIQUE
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'tinode'
AND COLLATION IS NOT NULL;
Особое внимание обрати на те, где NON_UNIQUE = 0 (т.е. уникальные индексы).
Если такие поля теперь сравниваются иначе — возможно появление конфликтов.
Если хочешь, я могу проанализировать вывод и сказать, есть ли риск.
Вот команда для дампа базы tinode, в актуальном состоянии с utf8mb4_0900_ai_ci:
bashmysqldump -u root -p \ --default-character-set=utf8mb4 \ --single-transaction \ --routines --triggers \ --set-charset \ tinode > tinode_final_utf8mb4_0900_ai_ci.sql
📁 Результирующий файл:
tinode_final_utf8mb4_0900_ai_ci.sql— будет включать всё, включая структуру, данные, процедуры, и актуальные COLLATE/CHARSET.
Проанализировать результаты SQL-запросов (если скопируешь сюда)
Помочь отфильтровать только уникальные строковые индексы
Проверить, осталась ли где-то utf8mb4_unicode_ci
Или собрать скрипт сравнения до/после миграции
Готов помочь с финальной проверкой!