Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 01/10/2006, 21h05   #1
Membre du Club
 
Inscription : décembre 2004
Messages : 52
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 52
Points : 53
Points : 53
Envoyer un message via ICQ à Galak`
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.
Galak` est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/10/2006, 22h29   #2
Provisoirement toléré
 
Avatar de Maximilian
 
Inscription : juin 2003
Messages : 2 622
Détails du profil
Informations forums :
Inscription : juin 2003
Messages : 2 622
Points : 2 505
Points : 2 505
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.

Citation:
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
__________________
Pensez au bouton
Maximilian est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/10/2006, 23h50   #3
Membre du Club
 
Inscription : décembre 2004
Messages : 52
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 52
Points : 53
Points : 53
Envoyer un message via ICQ à Galak`
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.
Galak` est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/10/2006, 03h55   #4
Membre du Club
 
Inscription : décembre 2004
Messages : 52
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 52
Points : 53
Points : 53
Envoyer un message via ICQ à Galak`
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.
Galak` est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h46.


 
 
 
 
Partenaires

Hébergement Web