Как исправить MySql: размер столбца индекса слишком велик (миграция Laravel)
Я продублировал проект с бродячей коробкой, которая устанавливает Debian, Nginx, PhpMyAdmin, .. С новым проектом Laravel's php artisan migrate
больше не работает, и я получаю ошибку:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1709 Index column size too large. The maximum column size is 767 bytes. (SQL: alter table `courses` add unique `courses_name_unique`(`na
me`))
Когда я делаю дамп (структура + данные) из рабочей базы данных проекта и импортирую ее в базу данных с ошибками при переносе, все в порядке, и создаются все таблицы, а данные импортируются.
Как я могу исправить размер, чтобы я мог запустить метод переноса?
6 ответов
Как вы можете видеть в сообщении об ошибке - "Максимальный размер столбца составляет 767 байт", если вы хотите создать индекс для него. VARCHAR(255)
столбец может занимать до 765 (255*3) байтов, используя utf8
и 1020 (255*4) байтов с использованием utf8mb4
, Это потому что в MySQL utf8
занимает до 3 байтов и utf8mb4
до 4 байтов (реальный UTF8). Таким образом, создавая VARCHAR(255)
(уникальный) индекс с utf8mb4
не удастся.
Это ваши варианты решения проблемы:
Установить параметры сортировки по умолчанию в my.ini
:
collation_server=utf8_unicode_ci
character_set_server=utf8
Установите параметры сортировки по умолчанию для базы данных при создании:
CREATE DATABASE IF NOT EXISTS `your_db` COLLATE 'utf8_unicode_ci'
Установите параметры сортировки по умолчанию для таблицы / столбца. (Я не рекомендую это)
Измените размер столбца на 190 (varchar(190)
) или менее.
Laravel 5.4 fix
Конфигурация сервера Mysql перезаписывается командой миграции Laravel. Он установит параметры сортировки и кодировки в версию конфигурации.
Изменить поля charset
а также collation
движка БД в конфигурационном файле базы данных, расположенном в config/database.php
,
..
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
//'charset' => 'utf8mb4',
//'collation' => 'utf8mb4_unicode_ci',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
..
Для Мариадб, обновите свой *my.cnf
файл со следующей конфигурацией,
innodb_default_row_format=dynamic
innodb_file_format=barracuda
innodb_file_per_table=true
innodb_large_prefix=true
Затем вы должны перезагрузить mariadb
сервис для обновления конфигурации для вступления в силу.
Три решения, каждое с недостатком:
MySQL 5.7 позволяет избежать этой проблемы. Подумайте об обновлении.
VARCHAR(255)
обычно это больше, чем необходимо. Если вы можете безопасно сжаться до 191 или меньше, ошибка исчезнет.Переключитесь на utf8 (с utf8mb4), если вам не нужны китайский или эмодзи.
Для Laravel 5.5 или выше измените в файле config/database.php движок на InnoDB ROW_FORMAT=DYNAMIC:
'connections' => [
...
'mysql' => [
...
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
]]
Благодаря ларакастам: https://laracasts.com/discuss/channels/eloquent/migrations-and-table-options-row-format
В App\Providers\AppServiceProvider.php импортируйте Schema
use Illuminate\Support\Facades\Schema;
и в boot()
функция добавить эту строку:
Schema::defaultStringLength(191);
По умолчанию MySQL использует набор символов utf8, что означает, что мы используем 3 байта на каждый 1 символ. Это означает, что тип столбца varchar(10) использует 30 байтов, в результате чего максимальный размер префикса для компактного формата строки будет эквивалентен varchar(255). Это 255 * 3 байта = 765 байтов, что на два байта меньше максимального значения в 767 байтов.
Если для innodb_large_prefix задано значение on и используется формат строки COMPRESSED или DYNAMIC, вы можете увеличить максимальный размер префикса до 65536 байт вместо 767 байт. На приведенной ниже диаграмме показана максимальная длина символа с большим префиксом InnoDB и [COMPRESSED| DYNAMIC] форматы строк. Эти значения, ожидаемые для utf8mb4, превышают максимальный размер строки таблицы, поэтому нет возможности выйти за эти пределы
Более подробная информация здесь https://discuss.pivotal.io/hc/en-us/articles/115004086747-Apps-are-down-due-to-the-Maximum-Column-Size-is-767-bytes-Constraint-in-MySQL
Также была эта проблема, что я только что сделал, был возвращен из utf8mb4_unicode_ci в utf8_unicode_ci в сценарии подключения БД
Работает с 5.5.52-MariaDB.
Установить всю кодировку на utf8_general_ci
(сервер, база данных, соединение).