Question sur les types de données de MySQL

Question sur les types de données de MySQL - SQL/NoSQL - Programmation

Marsh Posté le 19-09-2006 à 13:57:15    

Bonjour,
Je me pose qq questions sur la taille des types entiers de MySQL, à savoir TINYINT, SMALLINT, MEDIUMINT, INT et BIGINT.
Par défaut, sans rien mettre dans la colonne "Taille/Valeurs", j'ai :
TINYINT = 3 octets
SMALLINT = 5 octets
MEDIUMINT = 8 octets
INT = 10 octets
BIGINT = 20 octets
 
Pourtant, en lisant la doc, je m'aperçois que je devrais avoir :  
TINYINT = [0..255] -> 1 octet  
SMALLINT = [0..65535] -> 2 octets
MEDIUMINT = [0..16777215] -> 3 octets
INT = [0..4294967295] -> 4 octets
BIGINT = [0..18446744073709551615] -> 8 octets
 
Pourquoi une telle différence? Merci par avance.
 
ps : je ne m'intéresse quand nb >= 0, d'où pourquoi je n'ai pas mis les intervalles négatifs

Reply

Marsh Posté le 19-09-2006 à 13:57:15   

Reply

Marsh Posté le 19-09-2006 à 14:03:24    

question complémentaire : je veux stocker des chaînes de caractères de taille variable (max 255), mais je veux qu'une requête SQL où je mets champ="Valeur" ne me sorte pas le même résultat que champ="valeur" (que la requête soit sensible à la casse et aux accents). C'est bien le type "TINYBLOB" que je doit utiliser, non?

Reply

Marsh Posté le 19-09-2006 à 14:35:29    

:heink:
 
tu confondrais pas la taille avec la précision toi ?
 
car les chiffres que tu nous énonce sont justement la précision :
1 octet = 3 chiffres
2 octets = 5 chiffres
3 octets = 8 chiffres
4 octets = 10 chiffres
8 octets = 20 chiffres
 
:heink:

Reply

Marsh Posté le 19-09-2006 à 14:36:21    

pour ton problème de cast, c'est une option de configuration de MySQL.
c'est notamment sa locale qui est par défaut configurée n'importe comment (tri du dictionnaire)

Message cité 1 fois
Message édité par MagicBuzz le 19-09-2006 à 14:36:45
Reply

Marsh Posté le 19-09-2006 à 14:38:40    

MagicBuzz a écrit :

:heink:
 
tu confondrais pas la taille avec la précision toi ?
 
car les chiffres que tu nous énonce sont justement la précision :
1 octet = 3 chiffres
2 octets = 5 chiffres
3 octets = 8 chiffres
4 octets = 10 chiffres
8 octets = 20 chiffres
 
:heink:


 
pas bête, j'avais pas fait le rapprochement. Effectivement, ça doit être ça.

Reply

Marsh Posté le 19-09-2006 à 14:41:12    

MagicBuzz a écrit :

pour ton problème de cast, c'est une option de configuration de MySQL.
c'est notamment sa locale qui est par défaut configurée n'importe comment (tri du dictionnaire)


 
Je ne sais pas si je me suis bien exprimé. Je veux ce comportement juste pour un champ bien défini d'une de mes tables.

Reply

Marsh Posté le 19-09-2006 à 14:45:27    

Si MySQL n'est pas la dernière des merdes au niveau des SGBD, il te permettra de modifier ce paramètre pour un champ particulier dans une table particulière.
 
Si c'est effectivement la dernière des merdes, donc oui, t'as plus qu'à passer par un type Binaire.
 
Essaie quand même de passer par le type CHAR, ça restera quand même moi gore, et surtout indexable (et tant pis pour la perte de place)

Message cité 1 fois
Message édité par MagicBuzz le 19-09-2006 à 14:45:48
Reply

Marsh Posté le 19-09-2006 à 15:40:27    

MagicBuzz a écrit :

Si MySQL n'est pas la dernière des merdes au niveau des SGBD, il te permettra de modifier ce paramètre pour un champ particulier dans une table particulière.
 
Si c'est effectivement la dernière des merdes, donc oui, t'as plus qu'à passer par un type Binaire.
 
Essaie quand même de passer par le type CHAR, ça restera quand même moi gore, et surtout indexable (et tant pis pour la perte de place)


 
ben justement, c'est le champ sur lequel faut pas prendre de la place car il fait parti de la table qui va avoir le plus d'enregistrements... et ce champ, j'ai pas besoin de l'indexer.

Reply

Marsh Posté le 19-09-2006 à 15:47:41    

ben blob alors. mais c'est bien gore comme il faut, je te préviens

Reply

Marsh Posté le 20-09-2006 à 12:26:44    

MagicBuzz a écrit :

ben blob alors. mais c'est bien gore comme il faut, je te préviens


 
Tu peux préciser, svp? Merci.

Reply

Marsh Posté le 20-09-2006 à 12:26:44   

Reply

Marsh Posté le 20-09-2006 à 12:29:11    

blob, c'est en fait un bigint correspondant à un "pointeur" vers une zone du fichier de données.
et les données contenues dans le champs sont en réalité stockées "à la vas-y comme j'te pousse" dans cette zone.
 
niveau perfs, c'est donc abominable, et c'est donc plutôt réservé aux très gros volumes qu'on ne vient lire que ponctuellement un par un, et sur lesquels on ne fait aucune oppération.

Message cité 1 fois
Message édité par MagicBuzz le 20-09-2006 à 12:30:13
Reply

Marsh Posté le 20-09-2006 à 12:39:15    

MagicBuzz a écrit :

blob, c'est en fait un bigint correspondant à un "pointeur" vers une zone du fichier de données.
et les données contenues dans le champs sont en réalité stockées "à la vas-y comme j'te pousse" dans cette zone.
 
niveau perfs, c'est donc abominable, et c'est donc plutôt réservé aux très gros volumes qu'on ne vient lire que ponctuellement un par un, et sur lesquels on ne fait aucune oppération.


 
c'est intéressant ce que tu me dis là car justement, c'est sur ce champ que je vais faire plusieurs traitements (recherche, comparaison). Donc, il vaudrait mieux perdre de l'espace de stockage au profit des perfs, c'est bien ça?

Reply

Marsh Posté le 20-09-2006 à 14:11:28    

très clairement, oui.
 
l'espace disque, c'est quelque chose de peu coûteux. les vitesse d'accès, et la vitesse processeur, bien plus.
 
d'autant plus qu'un blob n'étant par définition pas indexable (sauf avec des index "texte", mais qui ne permettent pas ce que tu veux faire), cela implique des traîtements bien plus long pour le même résultat.
 
à noter d'ailleurs que MySQL est un des très rares SGBD à supporter "en natif" des oppérations de comparaison et traîtements sur des blob. la plupart des autres SGBD obligent à utiliser des fonctions dédiées, réputée très lentes (car souvent de simples scripts), afin de forcer les utilisateurs à n'y avoir recourt qu'en cas d'absolue nécessité.
 
dans tous les cas, il faut remettre à sa place ce qui doit l'être : un SGBD, c'est avant tout un outil qui permet de stocker et consulter de façon efficace de grands volumes d'informations. qui dit données et grand volume dit absence de recherche d'optimisations de bout de chandelle.
 
quand bien même chaque ligne de tes tables font 2 Mo et que tu as des millions de lignes dans ta table, tu n'as pas à te soucier de savoir si le SGBD va prendre du temps à relire les données : il est fait pour ça.
 
tout simplement parceque lorsque la table est correctement construite, les champs utilisés pour faire des filres sont correctement indexés, et ne seront donc effectivement lus qu'à la fin de l'exécution de la requête, afin de récupérer le résultat, en aucun cas lors des traitements pour retrouver ce dernier.
 
l'utilisation d'un type non indexable pour une donnée qui peut faire l'objet d'un filtre est donc contraire même au rôle du SGBD. ça l'est d'autant plus si ce choix vient uniquement d'un problème de souci d'économie d'espace disque, chose qui n'impacte pas du tout le fonctionnement du SGBD :)

Reply

Marsh Posté le 20-09-2006 à 16:37:23    

Tiens, voici le lien qui présente les tables que je veux implémenter : http://forum.hardware.fr/forum2.ph [...] 0#t1430090
 
Le champ en question est "Valeur" de la table "Attributs".
 
Voici 2 autres sujets concernant toujours le même problème :  
http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
 
D'après une première estimation, je vais avoir environ entre 200 000 et 300 000 enregistrements par an dans la table "Attributs". Les traitements de recherche et de comparaison vont porter sur les valeurs d'attributs de calculateurs. D'où ma question existentielle : quelle type de donnée pour le champ "Valeur" de la table "attributs" : CHAR(255), VARCHAR(255), TINYBLOB ou VARBINARY (qui doit être l'équivalent du VARCHAR avec l'attribut BINARY sous MySQL 3.23.xx je pense), sachant que je veux que mon champ soit sensible à la casse.
Si j'ai bien tout compris, dans mon cas d'utilisation, je devrais mettre VARBINARY(255) avec un index dessus (à cause des traitements de recherche et de comparaison), c'est bien ça?


Message édité par rufo le 20-09-2006 à 16:47:24
Reply

Marsh Posté le 20-09-2006 à 17:20:52    

drapal
 
EDIT : j'utiliserais un varchar(255) + index (voir clef primaire si c'est un identifiant unique) (mais bon suis pas un pro dans ce domaine ;))

Message cité 1 fois
Message édité par chani_t le 20-09-2006 à 17:23:06
Reply

Marsh Posté le 20-09-2006 à 17:45:46    

chani_t a écrit :

drapal
 
EDIT : j'utiliserais un varchar(255) + index (voir clef primaire si c'est un identifiant unique) (mais bon suis pas un pro dans ce domaine ;))


varchar n'est pas sensible à la casse, donc ça ne va pas (sauf si on lui met l'attribut binary) et je ne peux pas mettre ce champ en clef primaire car les valeurs sont pas uniques. Par ailleurs, je ne suis pas fan de mettre une chaîne de caractères en clef primaire, je préfère un entier. Je pense que ça présente trop de risques...

Reply

Marsh Posté le 20-09-2006 à 17:53:15    

varbinary me semble pas mal en effet, mais assure-toi quand même que tu peux le traîter comme une chaine de caractères...
 
sinon, pour le charset spécifique d'un champ, et le type de dictionnaire utilisé pour le tri, ça donne quoi ?
 
parceque clairement, dans l'absolu c'est ce qu'il ta faut (couplé à un varchar du coup)

Reply

Marsh Posté le 20-09-2006 à 20:13:37    

MagicBuzz a écrit :

varbinary me semble pas mal en effet, mais assure-toi quand même que tu peux le traîter comme une chaine de caractères...
 
sinon, pour le charset spécifique d'un champ, et le type de dictionnaire utilisé pour le tri, ça donne quoi ?
 
parceque clairement, dans l'absolu c'est ce qu'il ta faut (couplé à un varchar du coup)


 
je ne suis pas sûre de bien comprendre de quoi tu parles. le charset, tu fais référence au champ "interclassement" de mysql 5 qui peut prendre comme valeur "latin1_xxx"? Et type de dictionnaire, à quoi tu fais référence?

Reply

Marsh Posté le 21-09-2006 à 11:01:21    

le charset, c'est en effet latin1, unicode, etc.
et le type de dictionnaire, c'est justement la méthode utilisée pour trier et comparer les caractères.
 
par exemple, selon les dictionnaires, les comparaison/tris seront case-sensitive ou non. dans d'autres cas, les accents seront différenciés ou non. etc.
 
Informations pour SQL Server 2005 par exemple :
http://msdn2.microsoft.com/fr-fr/library/ms187582.aspx
 
Ici, ils expliquent que SQL Server 2005 permet de faire ce que je te propose de vérifier sous MySQL :
http://msdn2.microsoft.com/fr-fr/library/ms177439.aspx
http://msdn2.microsoft.com/fr-fr/library/ms190920.aspx
 
On voit que "LATIN1" est surtout suivit dans l'exemple de l'article par "CI_AS" qui veut dire "Case Insensitive et Accent Sensitive", ce qui correspond effectivement au classmement que tu trouveras dans ton Larousse.
http://msdn2.microsoft.com/fr-fr/library/ms180175.aspx

Reply

Marsh Posté le 21-09-2006 à 11:19:42    

apparemment, dans MySQL 5, y'a pas de AS, y'a que CI ou CS : http://dev.mysql.com/doc/refman/5. [...] mysql.html
 
Moi, je vais prendre "latin1_general_cs" je pense. De ce fait, ça veut dire que je peux typer mon champ en CHAR(255) avec pour interclassement "latin1_general_cs" pour gérer le case sensitive. Du reste, j'ai l'impression que pour MySQL, CS implique aussi AC...


Message édité par rufo le 21-09-2006 à 11:20:11
Reply

Marsh Posté le 21-09-2006 à 11:21:38    

logiquement, c'est ça.
fait le test.
 
si ça marche en tout cas, c'est mieux que tout le reste (normal, c'était ma première proposition :D)

Reply

Marsh Posté le 21-09-2006 à 11:40:51    

MagicBuzz a écrit :

logiquement, c'est ça.
fait le test.
 
si ça marche en tout cas, c'est mieux que tout le reste (normal, c'était ma première proposition :D)


 
je te remercie d'avoir attiré mon attention sur l'utilité de l'interclassement. Je dois avouer que j'avais laissé la valeur par défaut sans trop me poser de questions.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed