Optimisation requete/champ a 2 choix

Répondre
Sammuel
le 07/05/2008 à 20:33
Sammuel
Salut,

J'aimerais avoir votre avis concernant un truc tout simple.

Je m'explique :
***********
Une personne s'inscrit sur mon site. Cela ajoute un enregistrement dans la table 'user'.

Dans la table 'user', il y a un champ 'actif'. Ce champ est de type INT et peut etre égal soit à '0', soit à '1'.

Au moment de l'inscription, le champ 'actif' est égal à 0. Et l'utilisateur doit valider son inscription via un lien indiqué dans le mail d'inscription.

Si l'utilisateur clique sur ce lien, le champ actif est updaté et est égal à 1.
***********

J'aimerais savoir si il existe une autre solution pour gérer ce genre de chose, à savoir un champ avec 2 choix possible.

Sur ce genre de champ, est ce que c'est mieux si j'ajoute par défaut la valeur 'NULL' ?

Car par exemple, au moment de l'identification, ma requete sera du type :
SELECT username FROM user WHERE username = 'xxxx' AND password = 'yyyyy' AND actif IS NOT NULL


au lieu de :

SELECT username FROM user WHERE username = 'xxxx' AND password = 'yyyyy' AND actif = '1'


J'ai plusieurs champs de ce genre dans ma table... et j'ai pris l'habitude de les contrôler via des valeurs INT (soit = à 0, soit = à 1) mais ça ne doit pas être optimum au niveau des tables, et au niveau des requêtes. Donc, si vous auriez une petite astuce à me donner a ce sujet, je suis tout ouïe smiley

Merci !
Tiller
le 07/05/2008 à 20:47
Tiller
Je ne comprend pas vraiment en quoi contrôler via des valeurs INT n'est pas optimum comparé à 'NULL'

Certe pour la méthode 'NULL' il ne fait que vérifier s'il y a quelque chose donc on peut penser qu'il ne regarde pas la valeur, mais pour savoir qu'il n'y a rien, il regarde la valeur.
Pour l'INT c'est pareil, il regarde la valeur et la retourne.

Enfin je sais pas comment a été fait MySQL mais d'après moi l'INT est optimum, et si ce n'est pas le cas, il n'y absolument pas perte de puissance ou ralongement de la durée des requetes
Sammuel
le 08/05/2008 à 14:47
Sammuel
Je viens de regarder sur le net et pour des champs du genre Oui/Non, il faut utiliser :
TINYINT(1) => mais avec ce type de champs, je ne pourrais pas faire de requete en utilisant IS NULL/IS NOT NULL.
... Il y a ENUM aussi mais je ne pourrais pas utiliser IS NULL/IS NOT NULL.

Donc, autre solution, utiliser :
CHAR(0) NULL qui stockera une valeur binaire sur 1 seul bit. Et puis dans mes requetes, je pourrais jouer avec IS NULL/IS NOT NULL.

Je pense qu'en utilisant IS NULL/IS NOT NULL dans mes requetes, à la place de = '0' ou ='1', c'est plus efficace en terme de performance, non ?
Sammuel
le 08/05/2008 à 15:15
Sammuel
Je viens de lire ca dans la doc :
MySQL permet la création d'une colonne de type CHAR(0). Ceci est principalement utile dans de vieille application, qui ont besoin de la colonne, mais n'ont pas besoin de la valeur. C'est aussi pratique pour avoir une colonne à deux valeurs : un CHAR(0), qui n'est pas défini comme NOT NULL, va occuper un bit, et prendre deux valeurs : NULL ou ""
LupusMic
le 08/05/2008 à 20:28
LupusMic
Avec la table suivante :
create table users
( id integer auto_increment
, name char(10) not null
, is_active bool default null
, primary key (id)
) ;


On introduit les données suivantes :
insert into users (name) values ('Sammuel'), ('Tiller'), ('Lupus') ;


Les trois requêtes suivantes représentent respectivement les usagers actifs, désactivés et inactifs.

select * from users where is_active is true ;
select * from users where is_active is false ;
select * from users where is_active is null ;


Tu peux simplifier les deux premiers en :
select * from users where is_active ;
select * from users where not is_active ;


Pour activer un usager :
update users set is_active=true where name='Sammuel' ;

Pour désactiver ou suspendre un usager :
update users set is_active=false where name='Sammuel' ;


Pour forcer une reconfirmation d'inscription d'un usager :
update users set is_active=null where name='Sammuel' ;


Il faut faire attention à la chose suivante : false, null, true et l'ensemble des valeurs arithmétiques ne doivent pas être soumises entre guillemets. Pour t'en convaincre, exécutes ça dans un client mysql :
select true = 'true' ;
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Sammuel
le 09/05/2008 à 02:50
Sammuel
Merci pour ton explication LupusMic !

Donc, une requete du genre :
select * from users where is_active ;


...sera plus rapide que :
select * from users where is_active = '1' ;


?

J'avais lu ça quelque part, mais je ne sais plus ou. En faisant ça, c'était plus rapide, car mysql sautait une étape dans le traitement de la requête.

C'est un petit détail, mais au final sa peut faire la différence smiley
burnedsoul
le 09/05/2008 à 15:24
burnedsoul
Sympathique pour l'info, maintenant je doute de l'intérêt d'une telle démarche, tu dois avoir d'autres requêtes qui nécessitent vraiment une optimisation, car là, le gain doit se compter en millisecondes non ?
Webmaster de Clikmag http://www.clikmag.fr
Sammuel
le 09/05/2008 à 17:50
Sammuel
Le gain n'est pas énorme si tu n'as pas beaucoup d'enregistrements, mais tu gagnes quand même en poids/vitesse. Et plus tu as d'enregistrements, plus important sera le gain. Dommage que je n'ai pas de table importante pour faire un test smiley

Aussi, cela permet de simplifier les requêtes, de les rendre moins longues.

Ca ne coute rien de changer sa façon de coder, même si ce n'est qu'un petit détail, mais au final, ça + ça + ça, ça fera la différence ^^
LupusMic
le 10/05/2008 à 04:37
LupusMic
(Sammuel) Raaaaaahhhh !!! On ne représente pas le chiffre 1 par la chaîne '1' mais par la chaîne 1. Si tu persiste à ne pas faire la différence, attends-toi à avoir des surprises un jour (casts improbables, index inutilisés, etc).

(burnedsoul) Les millisecondes deviennent rapidement des secondes. Mais bon, n'optimise pas de suite, tu auras le temps de revoir l'optimisation au cas où.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Répondre

Ecrire un message

Votre message vient d'être créé avec succès.
LoadingChargement en cours