web-dev-qa-db-fra.com

Résolution: la clé spécifiée était trop longue; la longueur de clé maximale est de 767 octets

Notre serveur crée beaucoup de tables et l'une d'elles est le Lock_ table.

Nous utilisons MySQL 5.5 sur Percona. Nous utilisons également utf8_general_ci et utf8.

Il renvoie l'erreur suivante lors de la création de l'index suivant sur Lock_ table:

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

Voici la requête create-table:

create table Lock_ (
    uuid_ VARCHAR(75) null,
    lockId LONG not null primary key,
    companyId LONG,
    userId LONG,
    userName VARCHAR(75) null,
    createDate DATE null,
    className VARCHAR(75) null,
    key_ VARCHAR(200) null,
    owner VARCHAR(255) null,
    inheritable BOOLEAN,
    expirationDate DATE null
);

Requête d'index:

create unique index IX_DD635956 on Lock_ (className, key_, owner);

Ce problème se produit sur l'un de nos serveurs de production (auparavant, il s'agissait de mysql autonome, puis déplacé plus tard vers percona, mais le problème était présent dans les deux éditions), mais cela fonctionne bien sur notre environnement de développement.

Existe-t-il un moyen de mettre à jour la longueur d'index de l'environnement de production ou quelque chose pour qu'il ne génère pas cette erreur?

Merci

4
Prakash K

Je soupçonne que la différence est un problème de longueur Unicode. Comme vous n'utilisez pas un classement à un octet par caractère, la longueur totale des champs de votre clé est de 530 caractère (75 + 200 + 255 ) et non 530 octets , et 530 caractères pourraient facilement être plus de 767 octets selon la langue que vous stockez dans ces chaînes (en fait sera certainement si mysql stocke les données unicode toujours en deux octets par caractère comme le fait MS SQL Server dans son type de colonne NVARCHAR).

Quant à savoir pourquoi il travaille en Dev mais pas en direct:

  • Si mysql n'utilise pas un encodage de longueur fixe, il se pourrait que les données existantes dans certaines lignes en production soient suffisamment longues pour dépasser la limite de 767 octets, mais dans Dev, il n'y a pas de telles lignes. La fonction length() ( http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_length ) renvoie le nombre d'octets, pas afin de rechercher de telles lignes en sélectionnant où LENGTH(className)+LENGTH(key)+LENGTH(owner) > 767.
  • Sinon, il se peut que vos paramètres de classement ne soient pas identiques entre le développement et la production, essayez de les vérifier.
3
David Spillett

Votre taille totale d'index souhaitée pour (className, key_, owner) est:

(75*3 + 1 + 1) + (200*3 + 2 + 1) + (255*3 + 2 + 1) = 1598 bytes 

InnoDB autorise les index jusqu'à 3500 octets si chaque colonne indexe uniquement jusqu'à 767 octets . MyISAM n'autorise que 1000 caractères au total (modification de la taille du bloc). Votre base de données de production utilise probablement MyISAM au lieu d'InnoDB. Vous utilisez peut-être utf8mb4 en production? Cela vous obtiendrait cette erreur.

Jetez également un œil à pourquoi varchar (255) est une mauvaise idée .

2
jynus