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).
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