IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Procédural MySQL Discussion :

Champs CHAR 3 fois plus gros en UTF-8 ?


Sujet :

SQL Procédural MySQL

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 52
    Points : 97
    Points
    97
    Par défaut Champs CHAR 3 fois plus gros en UTF-8 ?
    Dans mes tests de migration d'ISO-8859-1 vers UTF-8, je pensais que la taille de la base ne serait pas trop impactée dans mon cas, la plupart des champs texte étant des champs de type CHAR (donc de taille fixe). Pourtant, je viens de constater qu'en changeant simplement l'interclassement (de latin1_swedish_ci vers utf8_general_ci) d'un champ d'une table de test contenant seulement un id et un champ CHAR(255), sa taille triple (au minimum), même si cette table ne contient que des caractères ASCII (donc identiques dans les 2 encodages). Par exemple en saisissant simplement une ligne avec pour valeur 'test', la table iso fait 257 octets contre 767 pour la table UTF-8 (et un test de conversion sur une table de 12Mo donne une table de 43Mo)

    Quelque chose doit m'échapper, mais j'avoue ne pas du tout voir quoi. Normalement, le champ de type CHAR(50) devrait faire 50 octets, quel que soit l'encodage et quel que soit son contenu. Les lettres accentués (par exemple) prenant simplement 2 de ces 50 octets en UTF-8, réduisant donc simplement le nombre de caractères pouvant être saisis dans ce champ.

    Ma base de donnée dépassant les 500Mo, je me vois mal la voir dépasser les 1.5Go suite à une éventuelle migration.

    Je n'ai pas passé 3h (mais bien une) à chercher l'explication mais je n'ai pour l'instant rien trouvé de probant.

  2. #2
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Salut,

    La longueur assignée à une colonne de type CHAR désigne bien le nombre de caractères qu'elle peut contenir, et pas le nombre d'octets.
    Un caractère au format UTF-8 pouvant prendre 3 octets sous MySQL (jusqu'à 4 dans le standard), il est normal que la taille prise par les colonnes CHAR triple lors de la conversion de latin1 à UTF-8.

    Je pense que tu gagnerais beaucoup à utiliser des VARCHAR.

    Tip: To save space with UTF-8, use VARCHAR instead of CHAR. Otherwise, MySQL must reserve three bytes for each character in a CHAR CHARACTER SET utf8 column because that is the maximum possible length. For example, MySQL must reserve 30 bytes for a CHAR(10) CHARACTER SET utf8 column.
    http://dev.mysql.com/doc/refman/5.0/...t-unicode.html

  3. #3
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 52
    Points : 97
    Points
    97
    Par défaut
    Oui, c'est bien ce qu'il me semblait, mais je ne savais pas que pour mysql c'était 3 octets. Je pensais à 4 et donc en concluais que ca ne devait pas être ca.
    Si j'utilise des CHAR, c'est pour avoir des tables de taille fixe. Je place les champs texte dans des tables séparées pour que la table principale de taille fixe ait de meilleurs performances. Mais effectivement, si on détermine la taille en caractères et non en octets, c'est trés problématique dans certains cas d'utilisation, avec 95% de caractères sur 1 octet et 5% sur 2...

    Je viens de vérifier et apparemment avec un VARCHAR, chaque caractère prend bien seulement le nombre réel d'octets qu'il utilise. Par contre, en tout cas avec phpMyAdmin, quand on ajoute un enregistrement uniquement ASCII dans une table UTF-8, le VARCHAR a tendance à prendre plus d'espace que dans une table ISO, mais si on modifie le type du champ (sans vraiment le changer, mais en faisant l'ALTER TABLE), le champ retrouve la taille correspondant à ce qu'il contient réellement. Ca se passe aussi comme ca avec une table ISO, mais le surplus d'espace pris par défaut est inférieur (en gros pour un VARCHAR de taille réelle 32 octets, on va avoir quelque chose comme 44 octets en ISO et 60 en UTF-8, avec retour à 32 si on fait un ALTER TABLE sur ce champ là). Bref tout ca pour dire que même si seuls quelques caractères passent sur 2 octets en UTF-8 avec des VARCHAR, si mysql gère aussi "mal" (si ca ne vient pas de phpMyAdmin, je n'ai pas testé depuis un script php) la taille de ses VARCHAR, on va quand même avoir une grosse perte de place en UTF-8.

    Bon bah du coup je pense que je vais en rester à l'ISO-8859-1 comme je le voulais au départ. J'ai de toute façon passé pas mal de temps à faire en sorte qu'on puisse à peu prêt saisir n'importe quel caractère unicode dans ma base ISO, avec diverses fonctions de conversion (caractères non représentés en ISO convertis en références numériques HTML entre autre), mais on se retrouve avec des € ou œ en clair dans la base, ce qui passe trés bien en pratique mais représente quand même un caractère non valide ISO-8859-1 dans le fond.

    Sinon, il faudrait que j'évalue les performances d'une table avec des VARCHAR comparé à la même table avec des CHAR. C'est un table assez grosse, mais justement, le gain important de poids en passant au VARCHAR (une table test de 15Mo passe à 6Mo avec des VARCHAR), compense peut-être les baisses de performance sur une table à taille variable.

  4. #4
    Membre régulier

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 52
    Points : 97
    Points
    97
    Par défaut
    J'ai fait pas mal de benches sur la différence CHAR/VARCHAR, rien de bien significatif sur les SELECT. Normalement ca ne change rien ou presque sur les INSERT et a une influence potentielle sur les UPDATE mais ce sont les requêtes les plus rares dans mon contexte donc exit les CHAR pour les champs non index de longueur assez variable et au dessus de 20 caractères (en gros), ca me fait entre autre passer une base de 400 à 145Mo...

    Reste à voir ce que ca donnera en passant en UTF-8, mais surement rien de bien méchant niveau poids.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/05/2007, 13h25
  2. Réponses: 31
    Dernier message: 07/12/2006, 11h46
  3. [FB] Concaterner un champ CHAR
    Par Neilos dans le forum SQL
    Réponses: 6
    Dernier message: 13/05/2006, 16h50
  4. Extraction des valeurs hexa d'un champ char
    Par Krispi dans le forum Fortran
    Réponses: 3
    Dernier message: 21/11/2005, 11h10
  5. Transformer un champ CHAR en décimal
    Par ALLB dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 19/07/2004, 13h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo