Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
842 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Pourquoi MySql force mes champs en varchar?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Pourquoi MySql force mes champs en varchar?

n°544586
saxgard
Posté le 20-10-2003 à 09:48:29  profilanswer
 

Voila
je sais qu'il faut eviter les champs de taille variable
Mais ce que je comprend pas c'ets que MySql force mes CHAR en VARCHAR
 
quand je met un champ de type CHAR (10) il me met VARCHAR automatiquement
 
pourquoi?
un char ne peu pas depasser 10 caractères? !!!  
 
ou alors c'est le systeme d'optimisation des base MySQL d'easyPHP qui merde?
 
merci d'avance

mood
Publicité
Posté le 20-10-2003 à 09:48:29  profilanswer
 

n°544631
Tunsen
Posté le 20-10-2003 à 10:33:37  profilanswer
 

Code :
  1. This is not a bug, it's documented in the manual.
  2. If there is one or more varchar types in a table, then
  3. every char field longer than 3 bytes are converted to varchars.
  4. And if there are one or more char fields (<= 3 bytes) then every
  5. varchar field <= 3 bytes are converted to chars.


Google est ton ami :)

n°544648
MagicBuzz
Posté le 20-10-2003 à 10:50:03  profilanswer
 

:heink:
 
et c'est quoi la raison de ce fonctionnement que je qualifierais de bizarre ?
 
cette liberté que prends le moteur de MySQL peut être extrêment emmerdante avec certaines applis qui nécessitent la présence des espaces obligatoires à la fin des champs... :/

n°544709
saxgard
Posté le 20-10-2003 à 11:29:27  profilanswer
 

c'est clair c chiant ce truc
 
et il y a aucun moyen de detourner ce truc?
 
si je veux unc champ de 40 caractères mais fix et donc en char , je peu pas?

n°544719
MagicBuzz
Posté le 20-10-2003 à 11:40:34  profilanswer
 

J'ai bien peut que non.
 
Doit y avoir une fonction style "format" qui devrait te permettre de forcer la taille du champ lors du select ou de l'insert.
 
(Tu ajoutes automatiquement les espaces manquants)
 
Tu peux tenter avec convert à la volée, c'est ce qui sera de plus propre, mais rien n'est sûr.
 
Avec SQL Server, ça serait :
 
select cast(champ as char(50)) as champDeLaBonneTaille from latable
 
Avec Oracle, pas de convertion ni de fonction, donc faut y aller à la mano :
 
select rpad(champ, 50) from latable


Message édité par MagicBuzz le 20-10-2003 à 11:51:37
n°544727
saxgard
Posté le 20-10-2003 à 11:48:35  profilanswer
 

oauis c bien dommage  ,
 d'autant pous que des champs a taille variable c'est pas tres bon pour l'optimisation enfin je crois

n°544740
MagicBuzz
Posté le 20-10-2003 à 11:52:33  profilanswer
 

-- Edit : Correction de la requête Oracle.
 
Comme une conversion vers du char, lpad et rpad d'Oracle retournent X caractères à partir du champ passé en paramètre, en ajoutant des espaces ou en tronquant si besoin.

n°544741
MagicBuzz
Posté le 20-10-2003 à 11:53:26  profilanswer
 

Saxgard a écrit :

oauis c bien dommage  ,
 d'autant pous que des champs a taille variable c'est pas tres bon pour l'optimisation enfin je crois  


T'inquiètes pas de l'optimisation, ça change vraiment pas grand chose, surtout que si tu te sert beaucoup de ce champ, alors il sera indexé, et à ce moment, quelque soit sa nature tu aura les mêmes performances.

n°544746
saxgard
Posté le 20-10-2003 à 11:56:53  profilanswer
 

MagicBuzz a écrit :


T'inquiètes pas de l'optimisation, ça change vraiment pas grand chose, surtout que si tu te sert beaucoup de ce champ, alors il sera indexé, et à ce moment, quelque soit sa nature tu aura les mêmes performances.


 
en paralnt d'indexation , ya t'il une limitte du nombre de champ que l'on peu indexé?
du type de champa  indexé etc..?

n°544762
MagicBuzz
Posté le 20-10-2003 à 12:03:39  profilanswer
 

oui, tous les SGBD ont une limitation pour tous les objets. Mais générallement, ça se comte en milliards pour les dernirères versions, donc pas de souci à ce niveau là.
 
Bon, pour le nombre de champs dans un même index, ça peut varier entre 64 et 256 généralement, mais jusqu'à 30, sûr et certain, aucun problème.

mood
Publicité
Posté le 20-10-2003 à 12:03:39  profilanswer
 

n°544768
saxgard
Posté le 20-10-2003 à 12:04:39  profilanswer
 

merci

n°544778
MagicBuzz
Posté le 20-10-2003 à 12:08:54  profilanswer
 

Spa terrible que je j'ai trouvé là...
 
The maximum number of keys and the maximum index length is defined per storage engine. See section 7 MySQL Table Types. You can with all storage engines have at least 16 keys and a total index length of at least 256 bytes.  
 
En fin de compte, MySQL semble ne pas aimerles trop gros indexes (m'enfin d'un autre côté, t'es pas censé avoir des indexes trop gros non plus, puisque sinon il ne sont plus performants...)

n°544853
saxgard
Posté le 20-10-2003 à 13:29:36  profilanswer
 

MagicBuzz a écrit :

Spa terrible que je j'ai trouvé là...
 
The maximum number of keys and the maximum index length is defined per storage engine. See section 7 MySQL Table Types. You can with all storage engines have at least 16 keys and a total index length of at least 256 bytes.  
 
En fin de compte, MySQL semble ne pas aimerles trop gros indexes (m'enfin d'un autre côté, t'es pas censé avoir des indexes trop gros non plus, puisque sinon il ne sont plus performants...)


 
bin enfait moi j'ai indexé 2-3 champs qui sont beacoup utilisés dans les WHERE  ;o)
ainsi que chaque clé primaire de chaque tables
 
je sais pas si c le bon raisonnement a  suivre  mais bon  ;o)

n°545116
MagicBuzz
Posté le 20-10-2003 à 15:20:41  profilanswer
 

si, c'est ça.
 
faudra que j'écrire un petit article là-dessus un de ces 4 à mettre dans la faq du forum. mais globalement c'est ça :
clé primaires : index unique
champs souvent utilisés dans les where, index, si possible unique.
toujours utiliser la totalité des champs des indexes. un seul index est utilisé par table et par query (si la table fait l'objet d'un alias dans la requête, alors chaque alias peut utiliser un index différent)

n°545130
saxgard
Posté le 20-10-2003 à 15:26:53  profilanswer
 

MagicBuzz a écrit :

si, c'est ça.
 
faudra que j'écrire un petit article là-dessus un de ces 4 à mettre dans la faq du forum. mais globalement c'est ça :
clé primaires : index unique
champs souvent utilisés dans les where, index, si possible unique.
toujours utiliser la totalité des champs des indexes. un seul index est utilisé par table et par query (si la table fait l'objet d'un alias dans la requête, alors chaque alias peut utiliser un index différent)


 
ouhla ca se complique
 
1 seul index par table et par query?
 
on peu avoir 3 index pour une table te se servir d'un seul index dans la requete? non ? ;o)

n°545148
MagicBuzz
Posté le 20-10-2003 à 15:35:21  profilanswer
 

Bah pour faire simple :
 
Tu peux avoir autant d'index que tu veux sur une table (plus tu en met, et plus ça va bouffer de la place et des ressources dans ta base).
Mais lors d'une requête, le parseur SQL va choisir quel index correspond le mieu à tes critères pour chaque requête portant dans chaque table.
 
Un exemple dans quelques instants

n°545152
drasche
Posté le 20-10-2003 à 15:37:18  profilanswer
 

je tombe sur ce topic et j'avais remarqué le même comportement, char <=3 ben ça donnait char sinon ça donnait varchar.
 
et là je suis en MySQL 4.0.14 (faudra que j'upgrade) et je remarque que à l'exception de 2 champs. Je ne m'explique même pas pourquoi car j'ai des char(255) dans mon modèle ET dans la base de données (que MySQL n'a donc pas jugé utile de convertir en varchar(255) :heink:


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
n°545156
saxgard
Posté le 20-10-2003 à 15:41:27  profilanswer
 

MagicBuzz a écrit :

Bah pour faire simple :
 
Tu peux avoir autant d'index que tu veux sur une table (plus tu en met, et plus ça va bouffer de la place et des ressources dans ta base).
Mais lors d'une requête, le parseur SQL va choisir quel index correspond le mieu à tes critères pour chaque requête portant dans chaque table.
 
Un exemple dans quelques instants


 
je te remercie

n°545157
MagicBuzz
Posté le 20-10-2003 à 15:41:29  profilanswer
 

table t1
      t1.c1
      t1.c2
      t1.c3
      t1.c4
 
table t2
      t2.c1
      t2.c2
      t2.c3
      t2.c4
 
t1.c1 et t2.c1, sont les clés primaires de tes tables.
t2.c2 est une clé étrangère pointant sur t1.c1. Il y a un index dessus
t2.c3 contient un flag sur lequel tu fait systématiquement un critère.
 
Tu vas donc créer les indexes suivant :
 
IDX1 (t1.c1) UNIQUE
IDX2 (t2.c1) UNIQUE
IDX3 (t2.c2, t2.c3) NON-UNIQUE
 
Maintenant, la requête :
 
select t2.c4
from t1, t2
where t1.c1 = '123'
and t2.c2 = t1.c1
and t2.c3 = 'ACTIVE'
 
Le SGBD va utiliser les index IDX1 pour la première (critère t1.c1 = '123', membre de l'index) et l'index IDX3 pour la seconde (critère t2.c2 = t1.c1 et t2.c3 = 'ACTIVE')
 
Par contre, imagine que tu rajoutes un critère sur c2.c1, style (and c2.c1 > 1000), vu que c'est un index unique, même si le critère est plus vague, c'est IDX2 qui va être utilisé à la place de IDX3.
 
Et imagine aussi que IDX3 porte aussi sur t2.c1, à ce moment il sera plus lent que s'il ne porte que sur t2.c2 et t2.c3, puisqu'il sera obligé de faire une "NESTED LOOP" dans l'index, ce qui est catastrophique niveau perfs (mais c'est toujours mieu que pas d'index du tout ;))


Message édité par MagicBuzz le 20-10-2003 à 15:43:31
n°545158
saxgard
Posté le 20-10-2003 à 15:41:36  profilanswer
 

drasche a écrit :

je tombe sur ce topic et j'avais remarqué le même comportement, char <=3 ben ça donnait char sinon ça donnait varchar.
 
et là je suis en MySQL 4.0.14 (faudra que j'upgrade) et je remarque que à l'exception de 2 champs. Je ne m'explique même pas pourquoi car j'ai des char(255) dans mon modèle ET dans la base de données (que MySQL n'a donc pas jugé utile de convertir en varchar(255) :heink:


 
oauis c louche  ;o)

n°545168
MagicBuzz
Posté le 20-10-2003 à 15:45:21  profilanswer
 

drasche a écrit :

je tombe sur ce topic et j'avais remarqué le même comportement, char <=3 ben ça donnait char sinon ça donnait varchar.
 
et là je suis en MySQL 4.0.14 (faudra que j'upgrade) et je remarque que à l'exception de 2 champs. Je ne m'explique même pas pourquoi car j'ai des char(255) dans mon modèle ET dans la base de données (que MySQL n'a donc pas jugé utile de convertir en varchar(255) :heink:


des char(255) c'est limite goret là par contre...
 
géneralement, un char on utilise ça pour écrire un code, qui sera indexé, genre un code produit, une code famille ou autre... Pas pour stocker du texte, parceque là, le gain que tu as avec un champ de taille fixe, tu le perds en surface occupée par le fichier sur le disque et en mémoire...

n°545181
drasche
Posté le 20-10-2003 à 15:52:40  profilanswer
 

c'est pas tellement la question, c'est plutôt que je me demande ce qui régit le mécanisme derrière pour choisir char ou varchar :D
 
bon en fait je viens de tester un truc, j'avais un varchar(255) suivi d'un mediumtext, et en fait c'est le seul que j'avais. J'arrivais pas à le changer en char, donc je supprime le champ mediumtext à tout hasard et là il me permet le changement de type en varchar. A mon avis c'était la présence d'un champ de type text/blob qui a influencé le choix de MySQL.


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
n°545202
MagicBuzz
Posté le 20-10-2003 à 16:03:17  profilanswer
 

Je sais que souvent les champs de ce type foutent le bordel dans les bases de données.
 
Par exemple lors d'une connection ODBC, un champ de type "text" sous SQL Server (un blob au format texte) va provoquer une erreur s'il n'est pas en dernière position dans la requête.
Avec Oracle, c'est encore mieu, par ODBC, ça plante tout court. Par OLE DB, ça merde à mort aussi, mais y'a une astuce pour que ça marche.
En fait, tant que ces champs peuvent être évités, il faut les éviter comme la peste, d'autant plus qu'ils ne peuvent pas être indexés avec des indexes classiques, donc offrent des performances catastrophiques dès qu'on fait un like dedans par exemple.

n°545209
drasche
Posté le 20-10-2003 à 16:06:42  profilanswer
 

pour ça pas de problème, j'en fais un usage parcimonieux et de toute façon, je suis sur PHP donc en natif MySQL directement.


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
n°545248
MagicBuzz
Posté le 20-10-2003 à 16:37:48  profilanswer
 

à mon avis ça empêche pas les merdes ;)
 
si Oracle et M$ ont ce bug connu depuis 10 ans et arrivent pas à s'en dépatouiller, alors même si MySQL a des points forts, je doute qu'ils soient passé à travers ce bordel sans y laisser des plumes ;)

n°545253
drasche
Posté le 20-10-2003 à 16:42:46  profilanswer
 

j'ai bien un argument fallacieux mais on va crier au troll [:meganne] (MySQL c'est libre donc forcément c'est corrigé depuis 10 ans :o)  Voilà j'ai quand même balancé discrètement mon troll :ange:
 
ben si le bug existe aussi chez MySQL je suppose que je le découvrirai dans pas très longtemps :D
 


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
n°545266
MagicBuzz
Posté le 20-10-2003 à 16:53:40  profilanswer
 

bah déjà, le fait que ton char soit converti ou non quand il y a un text à côté me semble être une manifestation oculte du bug en question ;)

n°545417
Tetedeienc​h
Head Of God
Posté le 20-10-2003 à 19:20:44  profilanswer
 

Alors ca !
 
C'est bien chiant !
 
Qu'est ce que j'en ai a faire de perdre de l'espace disque si c'est pour gagner en performances ?
 
Toutes les applis n'ayant pas le même profil, cette limitation de mySQL me semble dingue.
 
Cai super lourd si tu as des champs char assez longs et répétés, et surtout de taille fixe comme moi !
 
Débile même ! Perte de performance pour un gain disque NUL !

n°545448
mrbebert
Posté le 20-10-2003 à 19:54:56  profilanswer
 

drasche a écrit :

je tombe sur ce topic et j'avais remarqué le même comportement, char <=3 ben ça donnait char sinon ça donnait varchar.
 
et là je suis en MySQL 4.0.14 (faudra que j'upgrade) et je remarque que à l'exception de 2 champs. Je ne m'explique même pas pourquoi car j'ai des char(255) dans mon modèle ET dans la base de données (que MySQL n'a donc pas jugé utile de convertir en varchar(255) :heink:

Normalement, il ne fait ca QUE si les ligne sont de taille variable (il y a au moins un varchar/text). Ce qui est logique : dès qu'il y a une colonne ayant une taille non fixe, alors toute la ligne est de taille variable. Quitte à perdre les avantages des lignes de taille fixe, autant aller jusqu'au bout de la logique et convertir en varchar() toutes les colonnes de texte de longueur > 3 [:proy]


Message édité par mrbebert le 21-10-2003 à 07:19:16
n°545614
MagicBuzz
Posté le 20-10-2003 à 22:47:02  profilanswer
 

tetedeiench a écrit :

Alors ca !
 
C'est bien chiant !
 
Qu'est ce que j'en ai a faire de perdre de l'espace disque si c'est pour gagner en performances ?
 
Toutes les applis n'ayant pas le même profil, cette limitation de mySQL me semble dingue.
 
Cai super lourd si tu as des champs char assez longs et répétés, et surtout de taille fixe comme moi !
 
Débile même ! Perte de performance pour un gain disque NUL !


Non, tu ne gagnes pas en perfs si tu bouffe plus d'espace.
Réfléchit avec ton cerveau, il est là pour ça. ;)
 
Si ta table est plus grosse :
1) Les accès sur le disque représenteront forcément un parcours plus grand de têtes, donc un ralentissement majeur (en effet, sur un disque, c'est bien les déplacements des têtes qui sont les plus importants niveau performance)
2) Plus ta table est grosse, plus elle prendra de la place en mémoire, et plus tu auras besoin de charger/décharger des données lors des requêtes, donc plus d'accès disques.
 
Le gain de perfs avec un char est vrai quand t'as 1000 lignes. Au delà c'est au contraire un facteur bloquant.
 
C'est pas pour élever des moules dans le sahara que les développeurs de SGBD ont inventé les blob, qui ne sont qu'un int32 faisant référence à une zone du disque jamais utilisée plutôt que de perdre de la place dans les données des tables. C'est bien pour réduire la quantité d'informations à lire/traîter lorsqu'on fait des requêtes.
 
Sinon, un varchar n'a d'inconvénient que le fait que les champs sont de taille variable, donc ça force le moteur du SGBD à faire des calculs d'offset supplémentaires lors du traîtement des champs.
 
Seulement, si tu utilises ton champs pour un critère (seul moment où tu auras en effet besoin de lire très rapidement les valeurs) alors tu auras certainement fait un index (sinon je te fou mon poing sur ton gros nez) et par conséquent la différence de perfs est absoluement nulle (les calculs d'offset sont déjà présents dans l'index)


Message édité par MagicBuzz le 20-10-2003 à 22:53:40
n°545615
MagicBuzz
Posté le 20-10-2003 à 22:48:03  profilanswer
 

mrBebert a écrit :

Normalement, il ne fait ca QUE si les ligne sont de taille variable (il y a au moins un varchar/text). Ce qui est logique : dès qu'il y a une colonne ayant une taille non fixe, alors toute la ligne est de taille variable. Quitte à perdre les avantages des lignes de taille fixe, autant aller jusqu'au bout de la logique et convertir en varchar() toutes les colonnes de texte de longueur > 3 [:proy]  


Pour info, un champ de type "text" est de taille fixe au niveau de la table. La valeur est stockée à un autre endroit de la base. C'est ni plus ni moins qu'un pointeur, ou une "inode" quand on se met d'un point de vue système de fichier.


Message édité par MagicBuzz le 20-10-2003 à 22:48:56
n°545762
mrbebert
Posté le 21-10-2003 à 07:20:42  profilanswer
 

MySql indique que la table est à un format dynamique lorsqu'il y a une colonne 'text'. Mais c'est peut être effectivement géré différemment du varchar [:figti]

n°545805
MagicBuzz
Posté le 21-10-2003 à 09:26:17  profilanswer
 

Ben disons que si le type "text" était géré directement dans l'espace de stockage de la table, alors MySQL serait incapable d'offrir les performances qu'il offre actuellement, puisqu'un format "text" peut généralement contenir jusqu'à 4 Go de données (voir plus sur certain SGBD). A partir de là, je vois pas comment il serait possible de traîter efficacement tout ce volume de données lors de la recherche d'une ligne, simplement lors du chargement des autres colonnes en mémoire depuis le disque (parcequ'un déplacement de 4 Go sur un disque, ça fait un mouvement des têtes sur le disque, donc énorme temps de latence, surtout si c'est pour chaque ligne). Et le pire serait la place perdue, puisqu'une table avec du varchar par exemple est stockée avec des trous, permettant aux varchar de grossir sans devoir décaler toutes les données à chaque fois. Là avec une telle amplitude, le place perdue serait énorme, et les déplacement très fréquents.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Pourquoi MySql force mes champs en varchar?

 

Sujets relatifs
VC++7 et mysql[mysql] Undefined variable: PHPSESSID
remplacer les transactions sur MySQL et PHP[ PHP / MySQL ] requête de base ; résultat bizarre ...
MySQL / Free - requête qui marche pas ...[PHP/MySQL] Fichiers Texte ou Base de données ?
dev PHP en local et dB MySQL sur free[MySQL] similar_text ?
[MySQL] somme, moyenne, et autres statistiques[PHP/MySQL] Dilemne : stockage en base du texte au format HTML...
Plus de sujets relatifs à : Pourquoi MySql force mes champs en varchar?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR