web-dev-qa-db-fra.com

MariaDB 10.1.38 - La clé spécifiée était trop longue; la longueur de clé maximale est de 767 octets

J'ai un tableau qui a 3 colonnes:

id(int 11)  | user_id(int 4) | title(varchar 512) 
____________|________________|___________________
     1      |        3       | Thing X
     2      |        3       | Something Else
     3      |        5       | Thing X

Et je dois faire une combinaison unique entre user_id et title. Pour cela, j'utilise cette simple requête:

ALTER TABLE posts ADD UNIQUE `unique_post`(`user_id`, `title`)

Le jeu de caractères de la colonne title est utf8mb4_unicode_ci. La base de données a été créée à l'aide du jeu de caractères utf8mb4:

CREATE DATABASE learning_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Et le type de table est InnoDB.

J'ai essayé de définir quelques globales:

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=on;
SET GLOBAL innodb_large_prefix=on;

Mais je reçois la même erreur 1071:

Specified key was too long; max key length is 767 bytes

Y a-t-il autre chose que je pourrais faire?

P.S: si je mets à indexer uniquement le premier 191 caractères du title je ne reçois pas cette erreur:

ALTER TABLE posts ADD UNIQUE `unique_post`(`user_id`, `title`(191))

... mais j'ai des titres liés au même utilisateur qui peuvent être différents uniquement à la toute dernière lettre (alias 4 derniers octets compte tenu de mon jeu de caractères)

P.S.S: je suis sur localhost (en utilisant xampp).

1
Emanuel Ones

Ok donc après un week-end de recherche, la réponse est très simple et je vais la laisser ici pour les autres personnes confrontées à ce même problème.

Cette réponse est testée sur MariaDB 10.1.38, db charset utf8mb4, type de table InnoDB et jeu de caractères de table utf8mb4_unicode_ci:

Ouvert my.ini et ajoutez ces lignes (si elles existent déjà, modifiez tout après =) juste après [mysqld]:

innodb_file_format = Barracuda
innodb_file_per_table = on
innodb_default_row_format = dynamic
innodb_large_prefix = 1
innodb_file_format_max = Barracuda

Vous pouvez également les définir via le cmd/terminal:

Sous Windows - si votre xampp est situé à c:\xampp\:

Ouvrez un cmd et accédez au bac de mysql - dans ce cas:

cd c:\xampp\mysql\bin

Authentifier:

mysql -h localhost -u root

Une fois que vous êtes authentifié, exécutez ces requêtes (une à la fois):

SET GLOBAL innodb_file_format = Barracuda;
SET GLOBAL innodb_file_per_table = on
SET GLOBAL innodb_default_row_format = dynamic
SET GLOBAL innodb_large_prefix = 1
SET GLOBAL innodb_file_format_max = Barracuda

Mais je vous recommande de vous en tenir à l'édition de my.ini (ou .cnf) car si vous recherchez des requêtes, vos options pourraient être réécrites à chaque redémarrage d'Apache.

Vous pouvez en savoir plus sur le format de stockage InnoDB: ici

Cet article est également très intéressant pour vous aider à optimiser votre varchars avant de créer le unique keys: ici

2
Emanuel Ones