J'ai dupliqué un projet avec une boîte vagrant qui installe Debian, Nginx, PhpMyAdmin, .. Avec le nouveau projet, le php artisan migrate
de Laravel ne fonctionne plus et le message d'erreur suivant s'affiche:
[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`))
Lorsque je fais un cliché (structure + données) de la base de données du projet en cours de travail et que je l'importe dans la base de données en donnant les erreurs lors de la migration, tout est ok et crée toutes les tables et les données sont importées.
Comment puis-je corriger la taille afin que je puisse exécuter la méthode migrate?
Comme vous pouvez le constater dans le message d'erreur - "La taille de colonne maximale est de 767 octets", si vous souhaitez créer un index dessus. Une colonne VARCHAR(255)
peut contenir jusqu'à 765 octets (255 * 3) en utilisant utf8
et 1020 octets (255 * 4) en utilisant utf8mb4
. En effet, dans MySQL, utf8
prend jusqu'à 3 octets et utf8mb4
jusqu'à 4 octets (le vrai UTF8). Ainsi, la création d'un index VARCHAR(255)
(unique) avec utf8mb4
échouera.
Ce sont vos options pour résoudre le problème:
Définissez le classement par défaut dans my.ini
:
collation_server=utf8_unicode_ci
character_set_server=utf8
Définissez le classement par défaut pour la base de données lors de la création:
CREATE DATABASE IF NOT EXISTS `your_db` COLLATE 'utf8_unicode_ci'
Définir le classement par défaut pour la table/colonne. (Je ne recommande pas ça)
Modifiez la taille de la colonne à 190 (varchar(190)
) ou moins.
La configuration du serveur Mysql est écrasée par la commande de migration de Laravel. Il définira le classement et le jeu de caractères sur la version de la configuration.
Modifiez les champs charset
et collation
du moteur de base de données dans le fichier de configuration de la base de données situé dans 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,
],
..
Trois solutions, chacune avec un inconvénient:
MySQL 5.7 évite le problème. Envisager une mise à niveau.
VARCHAR(255)
est généralement plus grand que nécessaire . Si vous pouvez en toute sécurité réduire à 191 ou moins, l'erreur disparaîtra.
Passez à utf8 (à partir de utf8mb4), si vous n’avez pas besoin de chinois ou d’Emoji.
Pour mariadb, mettez à jour votre fichier *my.cnf
avec la configuration suivante,
innodb_default_row_format=dynamic
innodb_file_format=barracuda
innodb_file_per_table=true
innodb_large_prefix=true
Ensuite, vous devez redémarrer le service mariadb
pour que la configuration mise à jour prenne effet.
Par défaut, MySQL utilise le jeu de caractères utf8, ce qui signifie que nous utilisons 3 octets pour chaque caractère. Cela signifie que le type de colonne de varchar (10) utilise 30 octets, ce qui signifie que la taille de préfixe maximale du format de ligne compacte est équivalente à varchar (255). Cela correspond à 255 * 3 octets = 765 octets, soit deux octets de moins que le maximum de 767 octets.
Avec innodb_large_prefix défini sur on et en utilisant le format de ligne COMPRESSED ou DYNAMIC, vous pouvez augmenter la taille maximale du caractère de préfixe à 65 536 octets au lieu de 767 octets. Le graphique ci-dessous montre la longueur maximale de caractères avec le préfixe large InnoDB et [COMPRESSED | DYNAMIC] formats de lignes. Ces valeurs, attendues pour utf8mb4, sont supérieures à la taille de ligne maximale d'un tableau. Il est donc impossible de respecter ces limites.
Plus d'infos ici https://discuss.pivotal.io/hc/en-us/articles/115004086747-Apps-are-down-due-to-the-Maximum-Column-Size-is-767- bytes-Constraint-in-MySQL
Ce problème que je viens de faire est également passé de utf8mb4_unicode_ci à utf8_unicode_ci dans le script de connexion à la base
Cela fonctionne avec 5.5.52-MariaDB .
Définissez tous les codages surutf8_general_ci
(serveur, base de données, connexion).