web-dev-qa-db-fra.com

Comment réparer MySql: taille de colonne d'index trop grande (Laravel migrate)

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?

14
Sven van Zoelen

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.

Laravel 5.4 correctif

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,
        ],
..
34
Paul Spiegel

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.

4
Rick James

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.

2
cpxPratik

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

1

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

0
Fulela

Cela fonctionne avec 5.5.52-MariaDB

Définissez tous les codages surutf8_general_ci(serveur, base de données, connexion).

0
Anton